{
 "cells": [
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T15:51:46.595661Z",
     "start_time": "2025-02-25T15:51:39.170806Z"
    }
   },
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "from tqdm.auto import tqdm\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, torch:\n",
    "    print(module.__name__, module.__version__)\n",
    "    \n",
    "device = torch.device(\"cuda:0\") if torch.cuda.is_available() else torch.device(\"cpu\")\n",
    "print(device)\n"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sys.version_info(major=3, minor=12, micro=3, releaselevel='final', serial=0)\n",
      "matplotlib 3.10.0\n",
      "numpy 1.26.4\n",
      "pandas 2.2.3\n",
      "sklearn 1.6.1\n",
      "torch 2.6.0+cpu\n",
      "cpu\n"
     ]
    }
   ],
   "execution_count": 1
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 准备数据"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T15:51:47.062407Z",
     "start_time": "2025-02-25T15:51:46.597659Z"
    }
   },
   "source": [
    "from sklearn.datasets import fetch_california_housing\n",
    "\n",
    "housing = fetch_california_housing(data_home='data')\n",
    "print(housing.DESCR)\n",
    "print(housing.data.shape)\n",
    "print(housing.target.shape)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ".. _california_housing_dataset:\n",
      "\n",
      "California Housing dataset\n",
      "--------------------------\n",
      "\n",
      "**Data Set Characteristics:**\n",
      "\n",
      ":Number of Instances: 20640\n",
      "\n",
      ":Number of Attributes: 8 numeric, predictive attributes and the target\n",
      "\n",
      ":Attribute Information:\n",
      "    - MedInc        median income in block group\n",
      "    - HouseAge      median house age in block group\n",
      "    - AveRooms      average number of rooms per household\n",
      "    - AveBedrms     average number of bedrooms per household\n",
      "    - Population    block group population\n",
      "    - AveOccup      average number of household members\n",
      "    - Latitude      block group latitude\n",
      "    - Longitude     block group longitude\n",
      "\n",
      ":Missing Attribute Values: None\n",
      "\n",
      "This dataset was obtained from the StatLib repository.\n",
      "https://www.dcc.fc.up.pt/~ltorgo/Regression/cal_housing.html\n",
      "\n",
      "The target variable is the median house value for California districts,\n",
      "expressed in hundreds of thousands of dollars ($100,000).\n",
      "\n",
      "This dataset was derived from the 1990 U.S. census, using one row per census\n",
      "block group. A block group is the smallest geographical unit for which the U.S.\n",
      "Census Bureau publishes sample data (a block group typically has a population\n",
      "of 600 to 3,000 people).\n",
      "\n",
      "A household is a group of people residing within a home. Since the average\n",
      "number of rooms and bedrooms in this dataset are provided per household, these\n",
      "columns may take surprisingly large values for block groups with few households\n",
      "and many empty houses, such as vacation resorts.\n",
      "\n",
      "It can be downloaded/loaded using the\n",
      ":func:`sklearn.datasets.fetch_california_housing` function.\n",
      "\n",
      ".. rubric:: References\n",
      "\n",
      "- Pace, R. Kelley and Ronald Barry, Sparse Spatial Autoregressions,\n",
      "  Statistics and Probability Letters, 33 (1997) 291-297\n",
      "\n",
      "(20640, 8)\n",
      "(20640,)\n"
     ]
    }
   ],
   "execution_count": 2
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T15:51:47.071529Z",
     "start_time": "2025-02-25T15:51:47.063425Z"
    }
   },
   "source": [
    "# print(housing.data[0:5])\n",
    "import pprint  #打印的格式比较 好看\n",
    "\n",
    "pprint.pprint(housing.data[0:2])\n",
    "print('-'*50)\n",
    "pprint.pprint(housing.target[0:2])"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "array([[ 8.32520000e+00,  4.10000000e+01,  6.98412698e+00,\n",
      "         1.02380952e+00,  3.22000000e+02,  2.55555556e+00,\n",
      "         3.78800000e+01, -1.22230000e+02],\n",
      "       [ 8.30140000e+00,  2.10000000e+01,  6.23813708e+00,\n",
      "         9.71880492e-01,  2.40100000e+03,  2.10984183e+00,\n",
      "         3.78600000e+01, -1.22220000e+02]])\n",
      "--------------------------------------------------\n",
      "array([4.526, 3.585])\n"
     ]
    }
   ],
   "execution_count": 3
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T15:51:47.175397Z",
     "start_time": "2025-02-25T15:51:47.073527Z"
    }
   },
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "#拆分训练集和测试集，random_state是随机种子,同样的随机数种子，是为了得到同样的随机值\n",
    "x_train_all, x_test, y_train_all, y_test = train_test_split(\n",
    "    housing.data, housing.target, random_state = 7)\n",
    "x_train, x_valid, y_train, y_valid = train_test_split(\n",
    "    x_train_all, y_train_all, random_state = 11)\n",
    "# 训练集\n",
    "print(x_train.shape, y_train.shape)\n",
    "# 验证集\n",
    "print(x_valid.shape, y_valid.shape)\n",
    "# 测试集\n",
    "print(x_test.shape, y_test.shape)\n",
    "\n",
    "dataset_maps = {\n",
    "    \"train\": [x_train, y_train],\n",
    "    \"valid\": [x_valid, y_valid],\n",
    "    \"test\": [x_test, y_test],\n",
    "} #把3个数据集都放到字典中\n"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(11610, 8) (11610,)\n",
      "(3870, 8) (3870,)\n",
      "(5160, 8) (5160,)\n"
     ]
    }
   ],
   "execution_count": 4
  },
  {
   "cell_type": "code",
   "source": [
    "type(x_train)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T15:51:47.184618Z",
     "start_time": "2025-02-25T15:51:47.177682Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "numpy.ndarray"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 5
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T15:51:47.201717Z",
     "start_time": "2025-02-25T15:51:47.185624Z"
    }
   },
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "\n",
    "\n",
    "scaler = StandardScaler() #标准化\n",
    "scaler.fit(x_train) #fit和fit_transform的区别，fit是计算均值和方差，fit_transform是先fit，然后transform"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "StandardScaler()"
      ],
      "text/html": [
       "<style>#sk-container-id-1 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: #000;\n",
       "  --sklearn-color-text-muted: #666;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-1 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-1 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: flex;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "  align-items: start;\n",
       "  justify-content: space-between;\n",
       "  gap: 0.5em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label .caption {\n",
       "  font-size: 0.6rem;\n",
       "  font-weight: lighter;\n",
       "  color: var(--sklearn-color-text-muted);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-1 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-1 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 0.5em;\n",
       "  text-align: center;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-1 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>StandardScaler()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>StandardScaler</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.6/modules/generated/sklearn.preprocessing.StandardScaler.html\">?<span>Documentation for StandardScaler</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\"><pre>StandardScaler()</pre></div> </div></div></div></div>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 6
  },
  {
   "cell_type": "code",
   "source": [
    "np.array(1).shape"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T15:51:47.208879Z",
     "start_time": "2025-02-25T15:51:47.202718Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 7
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 构建数据集"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T15:51:47.223913Z",
     "start_time": "2025-02-25T15:51:47.209881Z"
    }
   },
   "source": [
    "#构建私有数据集，就需要用如下方式\n",
    "from torch.utils.data import Dataset\n",
    "\n",
    "class HousingDataset(Dataset):\n",
    "    def __init__(self, mode='train'):\n",
    "        self.x, self.y = dataset_maps[mode] #x,y都是ndarray类型\n",
    "        self.x = torch.from_numpy(scaler.transform(self.x)).float() #from_numpy将NumPy数组转换成PyTorch张量\n",
    "        self.y = torch.from_numpy(self.y).float().reshape(-1, 1) #处理为多行1列的tensor类型\n",
    "            \n",
    "    def __len__(self): #必须写\n",
    "        return len(self.x) #返回数据集的长度,0维的size\n",
    "    \n",
    "    def __getitem__(self, idx): #idx是索引，返回的是数据和标签，这里是一个样本\n",
    "        return self.x[idx], self.y[idx]\n",
    "    \n",
    "#train_ds是dataset类型的数据，与前面例子的FashionMNIST类型一致\n",
    "train_ds = HousingDataset(\"train\")\n",
    "valid_ds = HousingDataset(\"valid\")\n",
    "test_ds = HousingDataset(\"test\")"
   ],
   "outputs": [],
   "execution_count": 8
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T15:51:47.236970Z",
     "start_time": "2025-02-25T15:51:47.224913Z"
    }
   },
   "source": [
    "train_ds[0]"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([ 0.8015,  0.2722, -0.1162, -0.2023, -0.5431, -0.0210, -0.5898, -0.0824]),\n",
       " tensor([3.2260]))"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 9
  },
  {
   "cell_type": "code",
   "source": [
    "train_ds[0][0]"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T15:51:47.246739Z",
     "start_time": "2025-02-25T15:51:47.237971Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([ 0.8015,  0.2722, -0.1162, -0.2023, -0.5431, -0.0210, -0.5898, -0.0824])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 10
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### DataLoader"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T15:51:47.275354Z",
     "start_time": "2025-02-25T15:51:47.248739Z"
    }
   },
   "source": [
    "from torch.utils.data import DataLoader\n",
    "\n",
    "#放到DataLoader中的train_ds, valid_ds, test_ds都是dataset类型的数据\n",
    "batch_size = 16\n",
    "train_loader = DataLoader(train_ds, batch_size=batch_size, shuffle=True)\n",
    "val_loader = DataLoader(valid_ds, batch_size=batch_size, shuffle=False)\n",
    "test_loader = DataLoader(test_ds, batch_size=batch_size, shuffle=False)"
   ],
   "outputs": [],
   "execution_count": 11
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 定义模型"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T15:51:47.283758Z",
     "start_time": "2025-02-25T15:51:47.277729Z"
    }
   },
   "source": [
    "#回归模型我们只需要1个数\n",
    "\n",
    "class NeuralNetwork(nn.Module):\n",
    "    def __init__(self, input_dim=8):\n",
    "        super().__init__()\n",
    "        self.linear_relu_stack = nn.Sequential(\n",
    "            nn.Linear(input_dim, 30),\n",
    "            nn.ReLU(),\n",
    "            nn.Linear(30, 1)\n",
    "            )\n",
    "        \n",
    "    def forward(self, x):\n",
    "        # x.shape [batch size, 8]\n",
    "        logits = self.linear_relu_stack(x)\n",
    "        # logits.shape [batch size, 1]\n",
    "        return logits"
   ],
   "outputs": [],
   "execution_count": 12
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T15:51:47.300040Z",
     "start_time": "2025-02-25T15:51:47.285757Z"
    }
   },
   "source": [
    "class EarlyStopCallback:\n",
    "    def __init__(self, patience=5, min_delta=0.01):\n",
    "        \"\"\"\n",
    "\n",
    "        Args:\n",
    "            patience (int, optional): Number of epochs with no improvement after which training will be stopped.. Defaults to 5.\n",
    "            min_delta (float, optional): Minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute \n",
    "                change of less than min_delta, will count as no improvement. Defaults to 0.01.\n",
    "        \"\"\"\n",
    "        self.patience = patience\n",
    "        self.min_delta = min_delta\n",
    "        self.best_metric = -1\n",
    "        self.counter = 0\n",
    "        \n",
    "    def __call__(self, metric):\n",
    "        if metric >= self.best_metric + self.min_delta:\n",
    "            # update best metric\n",
    "            self.best_metric = metric\n",
    "            # reset counter \n",
    "            self.counter = 0\n",
    "        else: \n",
    "            self.counter += 1\n",
    "            \n",
    "    @property\n",
    "    def early_stop(self):\n",
    "        return self.counter >= self.patience\n"
   ],
   "outputs": [],
   "execution_count": 13
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T15:51:47.309692Z",
     "start_time": "2025-02-25T15:51:47.303037Z"
    }
   },
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "@torch.no_grad()\n",
    "def evaluating(model, dataloader, loss_fct):\n",
    "    loss_list = []\n",
    "    for datas, labels in dataloader:\n",
    "        datas = datas.to(device)\n",
    "        labels = labels.to(device)\n",
    "        # 前向计算\n",
    "        logits = model(datas)\n",
    "        loss = loss_fct(logits, labels)         # 验证集损失\n",
    "        loss_list.append(loss.item())\n",
    "        \n",
    "    return np.mean(loss_list)\n"
   ],
   "outputs": [],
   "execution_count": 14
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T15:53:09.453411Z",
     "start_time": "2025-02-25T15:51:47.310692Z"
    }
   },
   "source": [
    "# 训练\n",
    "def training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer,\n",
    "    early_stop_callback=None,\n",
    "    eval_step=500,\n",
    "    ):\n",
    "    record_dict = {\n",
    "        \"train\": [],\n",
    "        \"val\": []\n",
    "    }\n",
    "    \n",
    "    global_step = 0\n",
    "    model.train()\n",
    "    with tqdm(total=epoch * len(train_loader)) as pbar:\n",
    "        for epoch_id in range(epoch):\n",
    "            # training\n",
    "            for datas, labels in train_loader:#11610/16=725\n",
    "                datas = datas.to(device)\n",
    "                labels = labels.to(device)\n",
    "                # 梯度清空\n",
    "                optimizer.zero_grad()\n",
    "                # 模型前向计算\n",
    "                logits = model(datas) #得到预测值\n",
    "                # 计算损失\n",
    "                loss = loss_fct(logits, labels)\n",
    "                # 梯度回传\n",
    "                loss.backward()\n",
    "                # 调整优化器，包括学习率的变动等\n",
    "                optimizer.step()\n",
    " \n",
    "                loss = loss.cpu().item() #转为cpu类型，item()是取值\n",
    "                # record\n",
    "                \n",
    "                record_dict[\"train\"].append({\n",
    "                    \"loss\": loss, \"step\": global_step\n",
    "                })\n",
    "                \n",
    "                # evaluating\n",
    "                if global_step % eval_step == 0:\n",
    "                    model.eval()\n",
    "                    val_loss = evaluating(model, val_loader, loss_fct)\n",
    "                    record_dict[\"val\"].append({\n",
    "                        \"loss\": val_loss, \"step\": global_step\n",
    "                    })\n",
    "                    model.train()\n",
    "\n",
    "                    # 早停 Early Stop\n",
    "                    if early_stop_callback is not None:\n",
    "                        early_stop_callback(-val_loss) #根据验证集的损失来实现早停\n",
    "                        if early_stop_callback.early_stop:\n",
    "                            print(f\"Early stop at epoch {epoch_id} / global_step {global_step}\")\n",
    "                            return record_dict\n",
    "                    \n",
    "                # udate step\n",
    "                global_step += 1\n",
    "                pbar.update(1)\n",
    "                pbar.set_postfix({\"epoch\": epoch_id})\n",
    "        \n",
    "    return record_dict\n",
    "        \n",
    "\n",
    "epoch = 100\n",
    "\n",
    "model = NeuralNetwork()\n",
    "\n",
    "# 1. 定义损失函数 采用MSE损失,均方误差\n",
    "loss_fct = nn.MSELoss()\n",
    "# 2. 定义优化器 采用SGD\n",
    "# Optimizers specified in the torch.optim package\n",
    "optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)\n",
    "\n",
    "# 3. early stop\n",
    "early_stop_callback = EarlyStopCallback(patience=10, min_delta=1e-3)\n",
    "\n",
    "model = model.to(device)\n",
    "record = training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    early_stop_callback=early_stop_callback,\n",
    "    eval_step=len(train_loader)\n",
    "    )"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "  0%|          | 0/72600 [00:00<?, ?it/s]"
      ],
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "d7da35c37b674b9eaedc51ac744422f3"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Early stop at epoch 45 / global_step 32670\n"
     ]
    }
   ],
   "execution_count": 15
  },
  {
   "cell_type": "code",
   "source": [
    "record"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T15:53:09.522003Z",
     "start_time": "2025-02-25T15:53:09.458859Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'train': [{'loss': 5.448602676391602, 'step': 0},\n",
       "  {'loss': 8.861417770385742, 'step': 1},\n",
       "  {'loss': 8.359097480773926, 'step': 2},\n",
       "  {'loss': 6.201376914978027, 'step': 3},\n",
       "  {'loss': 6.128012657165527, 'step': 4},\n",
       "  {'loss': 7.559395790100098, 'step': 5},\n",
       "  {'loss': 4.63783073425293, 'step': 6},\n",
       "  {'loss': 5.03997278213501, 'step': 7},\n",
       "  {'loss': 6.0302534103393555, 'step': 8},\n",
       "  {'loss': 2.901233673095703, 'step': 9},\n",
       "  {'loss': 4.025794982910156, 'step': 10},\n",
       "  {'loss': 2.2005107402801514, 'step': 11},\n",
       "  {'loss': 3.7209882736206055, 'step': 12},\n",
       "  {'loss': 4.895859718322754, 'step': 13},\n",
       "  {'loss': 3.4160337448120117, 'step': 14},\n",
       "  {'loss': 4.022994041442871, 'step': 15},\n",
       "  {'loss': 1.86790132522583, 'step': 16},\n",
       "  {'loss': 2.251875400543213, 'step': 17},\n",
       "  {'loss': 2.905771017074585, 'step': 18},\n",
       "  {'loss': 1.3213618993759155, 'step': 19},\n",
       "  {'loss': 2.5492146015167236, 'step': 20},\n",
       "  {'loss': 0.8612642288208008, 'step': 21},\n",
       "  {'loss': 1.8643882274627686, 'step': 22},\n",
       "  {'loss': 1.5392056703567505, 'step': 23},\n",
       "  {'loss': 1.5954192876815796, 'step': 24},\n",
       "  {'loss': 1.4639441967010498, 'step': 25},\n",
       "  {'loss': 1.5332742929458618, 'step': 26},\n",
       "  {'loss': 1.561863660812378, 'step': 27},\n",
       "  {'loss': 1.6635915040969849, 'step': 28},\n",
       "  {'loss': 2.390519380569458, 'step': 29},\n",
       "  {'loss': 0.5752282738685608, 'step': 30},\n",
       "  {'loss': 1.1731187105178833, 'step': 31},\n",
       "  {'loss': 1.4363104104995728, 'step': 32},\n",
       "  {'loss': 2.1981372833251953, 'step': 33},\n",
       "  {'loss': 0.6801072955131531, 'step': 34},\n",
       "  {'loss': 1.0666884183883667, 'step': 35},\n",
       "  {'loss': 1.4469592571258545, 'step': 36},\n",
       "  {'loss': 0.9933832883834839, 'step': 37},\n",
       "  {'loss': 1.0353715419769287, 'step': 38},\n",
       "  {'loss': 0.7813984751701355, 'step': 39},\n",
       "  {'loss': 1.4607449769973755, 'step': 40},\n",
       "  {'loss': 1.2825372219085693, 'step': 41},\n",
       "  {'loss': 0.6243220567703247, 'step': 42},\n",
       "  {'loss': 0.9182870984077454, 'step': 43},\n",
       "  {'loss': 1.4651440382003784, 'step': 44},\n",
       "  {'loss': 0.8923512697219849, 'step': 45},\n",
       "  {'loss': 1.4652602672576904, 'step': 46},\n",
       "  {'loss': 1.3290550708770752, 'step': 47},\n",
       "  {'loss': 1.5378787517547607, 'step': 48},\n",
       "  {'loss': 1.0543034076690674, 'step': 49},\n",
       "  {'loss': 1.2567602396011353, 'step': 50},\n",
       "  {'loss': 1.7475504875183105, 'step': 51},\n",
       "  {'loss': 0.9998608827590942, 'step': 52},\n",
       "  {'loss': 2.2118608951568604, 'step': 53},\n",
       "  {'loss': 0.7908043265342712, 'step': 54},\n",
       "  {'loss': 1.2992238998413086, 'step': 55},\n",
       "  {'loss': 0.5674751996994019, 'step': 56},\n",
       "  {'loss': 0.7320238947868347, 'step': 57},\n",
       "  {'loss': 0.9215903282165527, 'step': 58},\n",
       "  {'loss': 1.118430256843567, 'step': 59},\n",
       "  {'loss': 0.5974026918411255, 'step': 60},\n",
       "  {'loss': 1.5427706241607666, 'step': 61},\n",
       "  {'loss': 0.7019005417823792, 'step': 62},\n",
       "  {'loss': 0.8604828119277954, 'step': 63},\n",
       "  {'loss': 1.0771902799606323, 'step': 64},\n",
       "  {'loss': 1.3231432437896729, 'step': 65},\n",
       "  {'loss': 1.337385892868042, 'step': 66},\n",
       "  {'loss': 1.1400169134140015, 'step': 67},\n",
       "  {'loss': 1.2709381580352783, 'step': 68},\n",
       "  {'loss': 0.6500632762908936, 'step': 69},\n",
       "  {'loss': 0.5814720392227173, 'step': 70},\n",
       "  {'loss': 1.7879376411437988, 'step': 71},\n",
       "  {'loss': 0.6139615178108215, 'step': 72},\n",
       "  {'loss': 0.49370303750038147, 'step': 73},\n",
       "  {'loss': 1.0113657712936401, 'step': 74},\n",
       "  {'loss': 0.7362377643585205, 'step': 75},\n",
       "  {'loss': 1.552323579788208, 'step': 76},\n",
       "  {'loss': 0.5242170691490173, 'step': 77},\n",
       "  {'loss': 0.582146942615509, 'step': 78},\n",
       "  {'loss': 0.6187418103218079, 'step': 79},\n",
       "  {'loss': 1.4681986570358276, 'step': 80},\n",
       "  {'loss': 0.9811124205589294, 'step': 81},\n",
       "  {'loss': 0.4982024133205414, 'step': 82},\n",
       "  {'loss': 0.28965508937835693, 'step': 83},\n",
       "  {'loss': 0.5894254446029663, 'step': 84},\n",
       "  {'loss': 0.30035126209259033, 'step': 85},\n",
       "  {'loss': 0.6743484735488892, 'step': 86},\n",
       "  {'loss': 1.4828921556472778, 'step': 87},\n",
       "  {'loss': 0.5755414366722107, 'step': 88},\n",
       "  {'loss': 0.5306071639060974, 'step': 89},\n",
       "  {'loss': 0.7815455794334412, 'step': 90},\n",
       "  {'loss': 0.4270203709602356, 'step': 91},\n",
       "  {'loss': 1.153825044631958, 'step': 92},\n",
       "  {'loss': 0.9674633741378784, 'step': 93},\n",
       "  {'loss': 0.787678062915802, 'step': 94},\n",
       "  {'loss': 1.392667531967163, 'step': 95},\n",
       "  {'loss': 0.3709762394428253, 'step': 96},\n",
       "  {'loss': 0.8626764416694641, 'step': 97},\n",
       "  {'loss': 0.460751473903656, 'step': 98},\n",
       "  {'loss': 0.8562926054000854, 'step': 99},\n",
       "  {'loss': 0.7890810966491699, 'step': 100},\n",
       "  {'loss': 0.7014708518981934, 'step': 101},\n",
       "  {'loss': 0.4516451060771942, 'step': 102},\n",
       "  {'loss': 0.49236616492271423, 'step': 103},\n",
       "  {'loss': 0.5493258237838745, 'step': 104},\n",
       "  {'loss': 0.9109054803848267, 'step': 105},\n",
       "  {'loss': 0.8126985430717468, 'step': 106},\n",
       "  {'loss': 0.3357868194580078, 'step': 107},\n",
       "  {'loss': 0.5666094422340393, 'step': 108},\n",
       "  {'loss': 0.394715815782547, 'step': 109},\n",
       "  {'loss': 0.5489863753318787, 'step': 110},\n",
       "  {'loss': 0.6550202369689941, 'step': 111},\n",
       "  {'loss': 0.3731163740158081, 'step': 112},\n",
       "  {'loss': 0.6212766170501709, 'step': 113},\n",
       "  {'loss': 0.27194324135780334, 'step': 114},\n",
       "  {'loss': 0.5163724422454834, 'step': 115},\n",
       "  {'loss': 1.720668077468872, 'step': 116},\n",
       "  {'loss': 0.20026597380638123, 'step': 117},\n",
       "  {'loss': 0.3080991506576538, 'step': 118},\n",
       "  {'loss': 0.43530896306037903, 'step': 119},\n",
       "  {'loss': 0.7978938221931458, 'step': 120},\n",
       "  {'loss': 0.9087666273117065, 'step': 121},\n",
       "  {'loss': 1.6786543130874634, 'step': 122},\n",
       "  {'loss': 0.4714149534702301, 'step': 123},\n",
       "  {'loss': 0.8837996125221252, 'step': 124},\n",
       "  {'loss': 1.1229883432388306, 'step': 125},\n",
       "  {'loss': 0.42869675159454346, 'step': 126},\n",
       "  {'loss': 0.5643527507781982, 'step': 127},\n",
       "  {'loss': 0.4551403820514679, 'step': 128},\n",
       "  {'loss': 1.0441426038742065, 'step': 129},\n",
       "  {'loss': 0.6718670725822449, 'step': 130},\n",
       "  {'loss': 0.6757109761238098, 'step': 131},\n",
       "  {'loss': 0.5425838232040405, 'step': 132},\n",
       "  {'loss': 2.0301334857940674, 'step': 133},\n",
       "  {'loss': 1.010157823562622, 'step': 134},\n",
       "  {'loss': 1.2997087240219116, 'step': 135},\n",
       "  {'loss': 0.4755585491657257, 'step': 136},\n",
       "  {'loss': 0.28905606269836426, 'step': 137},\n",
       "  {'loss': 0.40750652551651, 'step': 138},\n",
       "  {'loss': 0.5900249481201172, 'step': 139},\n",
       "  {'loss': 1.1401705741882324, 'step': 140},\n",
       "  {'loss': 0.4064960479736328, 'step': 141},\n",
       "  {'loss': 0.7886826992034912, 'step': 142},\n",
       "  {'loss': 1.4722250699996948, 'step': 143},\n",
       "  {'loss': 0.4204050302505493, 'step': 144},\n",
       "  {'loss': 0.40896522998809814, 'step': 145},\n",
       "  {'loss': 1.3968732357025146, 'step': 146},\n",
       "  {'loss': 0.6868425011634827, 'step': 147},\n",
       "  {'loss': 0.31428927183151245, 'step': 148},\n",
       "  {'loss': 0.5324690937995911, 'step': 149},\n",
       "  {'loss': 1.055047869682312, 'step': 150},\n",
       "  {'loss': 0.3300442099571228, 'step': 151},\n",
       "  {'loss': 0.30140042304992676, 'step': 152},\n",
       "  {'loss': 0.800046443939209, 'step': 153},\n",
       "  {'loss': 0.6612666249275208, 'step': 154},\n",
       "  {'loss': 0.5775881409645081, 'step': 155},\n",
       "  {'loss': 0.8090499639511108, 'step': 156},\n",
       "  {'loss': 0.6665390133857727, 'step': 157},\n",
       "  {'loss': 0.6624559164047241, 'step': 158},\n",
       "  {'loss': 0.5475274920463562, 'step': 159},\n",
       "  {'loss': 0.326489120721817, 'step': 160},\n",
       "  {'loss': 1.0608811378479004, 'step': 161},\n",
       "  {'loss': 0.9977532029151917, 'step': 162},\n",
       "  {'loss': 0.7107329368591309, 'step': 163},\n",
       "  {'loss': 0.3341826796531677, 'step': 164},\n",
       "  {'loss': 0.3017544448375702, 'step': 165},\n",
       "  {'loss': 0.38546448945999146, 'step': 166},\n",
       "  {'loss': 0.6939322352409363, 'step': 167},\n",
       "  {'loss': 0.5483019351959229, 'step': 168},\n",
       "  {'loss': 0.671683132648468, 'step': 169},\n",
       "  {'loss': 0.907781720161438, 'step': 170},\n",
       "  {'loss': 0.5569385886192322, 'step': 171},\n",
       "  {'loss': 0.3307805359363556, 'step': 172},\n",
       "  {'loss': 0.8287083506584167, 'step': 173},\n",
       "  {'loss': 0.341648131608963, 'step': 174},\n",
       "  {'loss': 0.8512100577354431, 'step': 175},\n",
       "  {'loss': 0.7281721830368042, 'step': 176},\n",
       "  {'loss': 0.4066273272037506, 'step': 177},\n",
       "  {'loss': 0.32556456327438354, 'step': 178},\n",
       "  {'loss': 0.923423707485199, 'step': 179},\n",
       "  {'loss': 0.2184848189353943, 'step': 180},\n",
       "  {'loss': 0.3856949508190155, 'step': 181},\n",
       "  {'loss': 0.9680029153823853, 'step': 182},\n",
       "  {'loss': 0.28459876775741577, 'step': 183},\n",
       "  {'loss': 0.827073335647583, 'step': 184},\n",
       "  {'loss': 1.1496987342834473, 'step': 185},\n",
       "  {'loss': 0.568472146987915, 'step': 186},\n",
       "  {'loss': 0.3052915334701538, 'step': 187},\n",
       "  {'loss': 0.5407502055168152, 'step': 188},\n",
       "  {'loss': 0.6413805484771729, 'step': 189},\n",
       "  {'loss': 0.21464501321315765, 'step': 190},\n",
       "  {'loss': 0.46708944439888, 'step': 191},\n",
       "  {'loss': 1.0997858047485352, 'step': 192},\n",
       "  {'loss': 1.1645399332046509, 'step': 193},\n",
       "  {'loss': 0.3411993980407715, 'step': 194},\n",
       "  {'loss': 0.8265820145606995, 'step': 195},\n",
       "  {'loss': 0.7765166163444519, 'step': 196},\n",
       "  {'loss': 0.2232539802789688, 'step': 197},\n",
       "  {'loss': 0.9655749201774597, 'step': 198},\n",
       "  {'loss': 0.6930621266365051, 'step': 199},\n",
       "  {'loss': 0.3760502338409424, 'step': 200},\n",
       "  {'loss': 0.5635802745819092, 'step': 201},\n",
       "  {'loss': 0.7648532390594482, 'step': 202},\n",
       "  {'loss': 0.5290759205818176, 'step': 203},\n",
       "  {'loss': 0.7438482642173767, 'step': 204},\n",
       "  {'loss': 0.41426771879196167, 'step': 205},\n",
       "  {'loss': 0.32124969363212585, 'step': 206},\n",
       "  {'loss': 0.4705459475517273, 'step': 207},\n",
       "  {'loss': 1.1975430250167847, 'step': 208},\n",
       "  {'loss': 0.514428973197937, 'step': 209},\n",
       "  {'loss': 1.476142406463623, 'step': 210},\n",
       "  {'loss': 0.39664360880851746, 'step': 211},\n",
       "  {'loss': 0.33249029517173767, 'step': 212},\n",
       "  {'loss': 0.6018290519714355, 'step': 213},\n",
       "  {'loss': 1.012069821357727, 'step': 214},\n",
       "  {'loss': 1.1391355991363525, 'step': 215},\n",
       "  {'loss': 0.3524497449398041, 'step': 216},\n",
       "  {'loss': 0.43297842144966125, 'step': 217},\n",
       "  {'loss': 0.5076038837432861, 'step': 218},\n",
       "  {'loss': 0.9845386147499084, 'step': 219},\n",
       "  {'loss': 0.7238901853561401, 'step': 220},\n",
       "  {'loss': 1.1664516925811768, 'step': 221},\n",
       "  {'loss': 0.27710360288619995, 'step': 222},\n",
       "  {'loss': 0.33451175689697266, 'step': 223},\n",
       "  {'loss': 0.8919305801391602, 'step': 224},\n",
       "  {'loss': 1.0228469371795654, 'step': 225},\n",
       "  {'loss': 0.2620142698287964, 'step': 226},\n",
       "  {'loss': 0.2756553590297699, 'step': 227},\n",
       "  {'loss': 0.5067471861839294, 'step': 228},\n",
       "  {'loss': 1.399079442024231, 'step': 229},\n",
       "  {'loss': 0.8034741282463074, 'step': 230},\n",
       "  {'loss': 0.6203242540359497, 'step': 231},\n",
       "  {'loss': 0.42206454277038574, 'step': 232},\n",
       "  {'loss': 0.3022865056991577, 'step': 233},\n",
       "  {'loss': 0.4094895124435425, 'step': 234},\n",
       "  {'loss': 0.7380669713020325, 'step': 235},\n",
       "  {'loss': 0.6504008769989014, 'step': 236},\n",
       "  {'loss': 0.6486576199531555, 'step': 237},\n",
       "  {'loss': 0.5412270426750183, 'step': 238},\n",
       "  {'loss': 0.9827820658683777, 'step': 239},\n",
       "  {'loss': 0.5493427515029907, 'step': 240},\n",
       "  {'loss': 0.8398652672767639, 'step': 241},\n",
       "  {'loss': 0.760360598564148, 'step': 242},\n",
       "  {'loss': 0.6902219653129578, 'step': 243},\n",
       "  {'loss': 0.684175968170166, 'step': 244},\n",
       "  {'loss': 0.3035390377044678, 'step': 245},\n",
       "  {'loss': 0.32553553581237793, 'step': 246},\n",
       "  {'loss': 0.6496872901916504, 'step': 247},\n",
       "  {'loss': 0.6795957684516907, 'step': 248},\n",
       "  {'loss': 0.49646487832069397, 'step': 249},\n",
       "  {'loss': 1.2378153800964355, 'step': 250},\n",
       "  {'loss': 0.6412743330001831, 'step': 251},\n",
       "  {'loss': 0.6318371295928955, 'step': 252},\n",
       "  {'loss': 0.29020875692367554, 'step': 253},\n",
       "  {'loss': 0.6937589645385742, 'step': 254},\n",
       "  {'loss': 0.2824237048625946, 'step': 255},\n",
       "  {'loss': 1.030465841293335, 'step': 256},\n",
       "  {'loss': 0.38438868522644043, 'step': 257},\n",
       "  {'loss': 0.9425628185272217, 'step': 258},\n",
       "  {'loss': 0.8276568651199341, 'step': 259},\n",
       "  {'loss': 0.7830137610435486, 'step': 260},\n",
       "  {'loss': 0.4245245158672333, 'step': 261},\n",
       "  {'loss': 0.3632735311985016, 'step': 262},\n",
       "  {'loss': 0.15187153220176697, 'step': 263},\n",
       "  {'loss': 0.41539695858955383, 'step': 264},\n",
       "  {'loss': 0.9078316688537598, 'step': 265},\n",
       "  {'loss': 0.4402591288089752, 'step': 266},\n",
       "  {'loss': 1.5690830945968628, 'step': 267},\n",
       "  {'loss': 0.24565976858139038, 'step': 268},\n",
       "  {'loss': 0.35208529233932495, 'step': 269},\n",
       "  {'loss': 0.6806665062904358, 'step': 270},\n",
       "  {'loss': 0.39148008823394775, 'step': 271},\n",
       "  {'loss': 0.7496544122695923, 'step': 272},\n",
       "  {'loss': 0.11414817720651627, 'step': 273},\n",
       "  {'loss': 0.5451592206954956, 'step': 274},\n",
       "  {'loss': 0.6059542298316956, 'step': 275},\n",
       "  {'loss': 0.9910263419151306, 'step': 276},\n",
       "  {'loss': 1.0902034044265747, 'step': 277},\n",
       "  {'loss': 0.309649258852005, 'step': 278},\n",
       "  {'loss': 0.3606102466583252, 'step': 279},\n",
       "  {'loss': 0.8136813640594482, 'step': 280},\n",
       "  {'loss': 1.0972647666931152, 'step': 281},\n",
       "  {'loss': 0.3629762828350067, 'step': 282},\n",
       "  {'loss': 0.895690381526947, 'step': 283},\n",
       "  {'loss': 0.32681649923324585, 'step': 284},\n",
       "  {'loss': 0.6334350109100342, 'step': 285},\n",
       "  {'loss': 0.4379671812057495, 'step': 286},\n",
       "  {'loss': 0.4698958694934845, 'step': 287},\n",
       "  {'loss': 0.6690449118614197, 'step': 288},\n",
       "  {'loss': 0.6622332334518433, 'step': 289},\n",
       "  {'loss': 0.5929050445556641, 'step': 290},\n",
       "  {'loss': 0.726128101348877, 'step': 291},\n",
       "  {'loss': 0.2541266679763794, 'step': 292},\n",
       "  {'loss': 0.20588111877441406, 'step': 293},\n",
       "  {'loss': 0.6004413366317749, 'step': 294},\n",
       "  {'loss': 1.1761443614959717, 'step': 295},\n",
       "  {'loss': 0.47710946202278137, 'step': 296},\n",
       "  {'loss': 0.6705194115638733, 'step': 297},\n",
       "  {'loss': 0.42470961809158325, 'step': 298},\n",
       "  {'loss': 0.5270674228668213, 'step': 299},\n",
       "  {'loss': 0.9277300834655762, 'step': 300},\n",
       "  {'loss': 0.11300206184387207, 'step': 301},\n",
       "  {'loss': 1.2145135402679443, 'step': 302},\n",
       "  {'loss': 1.0187143087387085, 'step': 303},\n",
       "  {'loss': 0.27334365248680115, 'step': 304},\n",
       "  {'loss': 0.45380982756614685, 'step': 305},\n",
       "  {'loss': 0.20319975912570953, 'step': 306},\n",
       "  {'loss': 0.9638843536376953, 'step': 307},\n",
       "  {'loss': 1.533610224723816, 'step': 308},\n",
       "  {'loss': 0.22639399766921997, 'step': 309},\n",
       "  {'loss': 0.42449426651000977, 'step': 310},\n",
       "  {'loss': 0.8928348422050476, 'step': 311},\n",
       "  {'loss': 0.17066636681556702, 'step': 312},\n",
       "  {'loss': 0.3513004183769226, 'step': 313},\n",
       "  {'loss': 0.2000293731689453, 'step': 314},\n",
       "  {'loss': 0.9768084287643433, 'step': 315},\n",
       "  {'loss': 0.8760866522789001, 'step': 316},\n",
       "  {'loss': 0.14616833627223969, 'step': 317},\n",
       "  {'loss': 0.4691430628299713, 'step': 318},\n",
       "  {'loss': 0.6036199331283569, 'step': 319},\n",
       "  {'loss': 0.24776694178581238, 'step': 320},\n",
       "  {'loss': 0.9902853965759277, 'step': 321},\n",
       "  {'loss': 0.5954938530921936, 'step': 322},\n",
       "  {'loss': 0.8488105535507202, 'step': 323},\n",
       "  {'loss': 0.3781962990760803, 'step': 324},\n",
       "  {'loss': 0.6321253180503845, 'step': 325},\n",
       "  {'loss': 0.6053655743598938, 'step': 326},\n",
       "  {'loss': 0.2364831566810608, 'step': 327},\n",
       "  {'loss': 0.2410334050655365, 'step': 328},\n",
       "  {'loss': 0.23615843057632446, 'step': 329},\n",
       "  {'loss': 0.6948176622390747, 'step': 330},\n",
       "  {'loss': 0.5168536901473999, 'step': 331},\n",
       "  {'loss': 1.2638022899627686, 'step': 332},\n",
       "  {'loss': 0.48172271251678467, 'step': 333},\n",
       "  {'loss': 0.6931979656219482, 'step': 334},\n",
       "  {'loss': 0.21338015794754028, 'step': 335},\n",
       "  {'loss': 0.6794134378433228, 'step': 336},\n",
       "  {'loss': 0.30903545022010803, 'step': 337},\n",
       "  {'loss': 0.3244468569755554, 'step': 338},\n",
       "  {'loss': 0.41767701506614685, 'step': 339},\n",
       "  {'loss': 0.6454051733016968, 'step': 340},\n",
       "  {'loss': 0.8306496143341064, 'step': 341},\n",
       "  {'loss': 1.0442135334014893, 'step': 342},\n",
       "  {'loss': 0.7462596297264099, 'step': 343},\n",
       "  {'loss': 0.5134729146957397, 'step': 344},\n",
       "  {'loss': 0.40519094467163086, 'step': 345},\n",
       "  {'loss': 1.5238500833511353, 'step': 346},\n",
       "  {'loss': 0.20236337184906006, 'step': 347},\n",
       "  {'loss': 0.78715580701828, 'step': 348},\n",
       "  {'loss': 0.18132032454013824, 'step': 349},\n",
       "  {'loss': 0.7088527679443359, 'step': 350},\n",
       "  {'loss': 1.9063602685928345, 'step': 351},\n",
       "  {'loss': 0.415054053068161, 'step': 352},\n",
       "  {'loss': 0.3401342034339905, 'step': 353},\n",
       "  {'loss': 0.40482544898986816, 'step': 354},\n",
       "  {'loss': 0.8839269876480103, 'step': 355},\n",
       "  {'loss': 0.6291444301605225, 'step': 356},\n",
       "  {'loss': 0.21204634010791779, 'step': 357},\n",
       "  {'loss': 0.629277765750885, 'step': 358},\n",
       "  {'loss': 0.6538596153259277, 'step': 359},\n",
       "  {'loss': 0.4803856611251831, 'step': 360},\n",
       "  {'loss': 0.6357018351554871, 'step': 361},\n",
       "  {'loss': 0.4209982454776764, 'step': 362},\n",
       "  {'loss': 2.8548638820648193, 'step': 363},\n",
       "  {'loss': 0.8378846049308777, 'step': 364},\n",
       "  {'loss': 0.46009406447410583, 'step': 365},\n",
       "  {'loss': 0.6009851694107056, 'step': 366},\n",
       "  {'loss': 0.45224615931510925, 'step': 367},\n",
       "  {'loss': 0.3505244553089142, 'step': 368},\n",
       "  {'loss': 0.8941174745559692, 'step': 369},\n",
       "  {'loss': 0.5910027027130127, 'step': 370},\n",
       "  {'loss': 0.820237934589386, 'step': 371},\n",
       "  {'loss': 0.24195381999015808, 'step': 372},\n",
       "  {'loss': 0.35248181223869324, 'step': 373},\n",
       "  {'loss': 0.09455087780952454, 'step': 374},\n",
       "  {'loss': 0.3256891369819641, 'step': 375},\n",
       "  {'loss': 0.40815943479537964, 'step': 376},\n",
       "  {'loss': 0.9375756978988647, 'step': 377},\n",
       "  {'loss': 0.2501821517944336, 'step': 378},\n",
       "  {'loss': 0.33945611119270325, 'step': 379},\n",
       "  {'loss': 0.8047633171081543, 'step': 380},\n",
       "  {'loss': 1.1167402267456055, 'step': 381},\n",
       "  {'loss': 0.14307789504528046, 'step': 382},\n",
       "  {'loss': 0.2608073651790619, 'step': 383},\n",
       "  {'loss': 0.7013964653015137, 'step': 384},\n",
       "  {'loss': 0.347258985042572, 'step': 385},\n",
       "  {'loss': 0.6676527261734009, 'step': 386},\n",
       "  {'loss': 0.640715479850769, 'step': 387},\n",
       "  {'loss': 0.5967340469360352, 'step': 388},\n",
       "  {'loss': 0.8750680685043335, 'step': 389},\n",
       "  {'loss': 0.289093554019928, 'step': 390},\n",
       "  {'loss': 0.6791068315505981, 'step': 391},\n",
       "  {'loss': 0.3097764253616333, 'step': 392},\n",
       "  {'loss': 0.49014848470687866, 'step': 393},\n",
       "  {'loss': 0.16302303969860077, 'step': 394},\n",
       "  {'loss': 0.8270987272262573, 'step': 395},\n",
       "  {'loss': 0.5609145760536194, 'step': 396},\n",
       "  {'loss': 0.20093297958374023, 'step': 397},\n",
       "  {'loss': 0.4590810537338257, 'step': 398},\n",
       "  {'loss': 0.3293340802192688, 'step': 399},\n",
       "  {'loss': 0.2227000594139099, 'step': 400},\n",
       "  {'loss': 0.27311354875564575, 'step': 401},\n",
       "  {'loss': 0.5148404836654663, 'step': 402},\n",
       "  {'loss': 0.7015315890312195, 'step': 403},\n",
       "  {'loss': 0.31080353260040283, 'step': 404},\n",
       "  {'loss': 0.794230580329895, 'step': 405},\n",
       "  {'loss': 0.48565372824668884, 'step': 406},\n",
       "  {'loss': 0.8383059501647949, 'step': 407},\n",
       "  {'loss': 0.5055928230285645, 'step': 408},\n",
       "  {'loss': 0.8055051565170288, 'step': 409},\n",
       "  {'loss': 0.19535398483276367, 'step': 410},\n",
       "  {'loss': 0.720987856388092, 'step': 411},\n",
       "  {'loss': 0.5348644852638245, 'step': 412},\n",
       "  {'loss': 0.21015147864818573, 'step': 413},\n",
       "  {'loss': 0.28913065791130066, 'step': 414},\n",
       "  {'loss': 0.38106149435043335, 'step': 415},\n",
       "  {'loss': 0.5752245187759399, 'step': 416},\n",
       "  {'loss': 0.38711318373680115, 'step': 417},\n",
       "  {'loss': 0.4229915738105774, 'step': 418},\n",
       "  {'loss': 0.6373081803321838, 'step': 419},\n",
       "  {'loss': 0.26104703545570374, 'step': 420},\n",
       "  {'loss': 0.36870521306991577, 'step': 421},\n",
       "  {'loss': 0.3547377586364746, 'step': 422},\n",
       "  {'loss': 0.4944259226322174, 'step': 423},\n",
       "  {'loss': 0.7230362892150879, 'step': 424},\n",
       "  {'loss': 0.5505325794219971, 'step': 425},\n",
       "  {'loss': 0.5075131058692932, 'step': 426},\n",
       "  {'loss': 0.7270400524139404, 'step': 427},\n",
       "  {'loss': 0.573406457901001, 'step': 428},\n",
       "  {'loss': 0.22794006764888763, 'step': 429},\n",
       "  {'loss': 0.35433197021484375, 'step': 430},\n",
       "  {'loss': 0.5227670669555664, 'step': 431},\n",
       "  {'loss': 0.12590914964675903, 'step': 432},\n",
       "  {'loss': 0.828258752822876, 'step': 433},\n",
       "  {'loss': 0.6540614366531372, 'step': 434},\n",
       "  {'loss': 0.3320636749267578, 'step': 435},\n",
       "  {'loss': 0.5636977553367615, 'step': 436},\n",
       "  {'loss': 0.19678649306297302, 'step': 437},\n",
       "  {'loss': 0.2782970368862152, 'step': 438},\n",
       "  {'loss': 0.35749635100364685, 'step': 439},\n",
       "  {'loss': 0.3991253674030304, 'step': 440},\n",
       "  {'loss': 0.35455209016799927, 'step': 441},\n",
       "  {'loss': 0.1481809914112091, 'step': 442},\n",
       "  {'loss': 0.4356931746006012, 'step': 443},\n",
       "  {'loss': 0.21028409898281097, 'step': 444},\n",
       "  {'loss': 0.5694504380226135, 'step': 445},\n",
       "  {'loss': 1.1035672426223755, 'step': 446},\n",
       "  {'loss': 0.573952317237854, 'step': 447},\n",
       "  {'loss': 0.4288467764854431, 'step': 448},\n",
       "  {'loss': 0.3781501054763794, 'step': 449},\n",
       "  {'loss': 0.4360077977180481, 'step': 450},\n",
       "  {'loss': 0.38264837861061096, 'step': 451},\n",
       "  {'loss': 1.3198821544647217, 'step': 452},\n",
       "  {'loss': 0.37255117297172546, 'step': 453},\n",
       "  {'loss': 0.4201332628726959, 'step': 454},\n",
       "  {'loss': 0.15389664471149445, 'step': 455},\n",
       "  {'loss': 0.43794602155685425, 'step': 456},\n",
       "  {'loss': 0.670199453830719, 'step': 457},\n",
       "  {'loss': 0.25277790427207947, 'step': 458},\n",
       "  {'loss': 0.2957335412502289, 'step': 459},\n",
       "  {'loss': 0.884590744972229, 'step': 460},\n",
       "  {'loss': 1.919076681137085, 'step': 461},\n",
       "  {'loss': 0.29303082823753357, 'step': 462},\n",
       "  {'loss': 0.36935877799987793, 'step': 463},\n",
       "  {'loss': 0.48760953545570374, 'step': 464},\n",
       "  {'loss': 0.23913180828094482, 'step': 465},\n",
       "  {'loss': 0.8162177801132202, 'step': 466},\n",
       "  {'loss': 0.2794295847415924, 'step': 467},\n",
       "  {'loss': 0.5855112075805664, 'step': 468},\n",
       "  {'loss': 0.5671361684799194, 'step': 469},\n",
       "  {'loss': 0.28405508399009705, 'step': 470},\n",
       "  {'loss': 0.1688249707221985, 'step': 471},\n",
       "  {'loss': 0.3478649854660034, 'step': 472},\n",
       "  {'loss': 0.8090600371360779, 'step': 473},\n",
       "  {'loss': 1.5860798358917236, 'step': 474},\n",
       "  {'loss': 0.3184068202972412, 'step': 475},\n",
       "  {'loss': 0.5401195287704468, 'step': 476},\n",
       "  {'loss': 0.21483063697814941, 'step': 477},\n",
       "  {'loss': 0.42055195569992065, 'step': 478},\n",
       "  {'loss': 0.9999673366546631, 'step': 479},\n",
       "  {'loss': 0.7084665894508362, 'step': 480},\n",
       "  {'loss': 0.4543852210044861, 'step': 481},\n",
       "  {'loss': 0.4619169533252716, 'step': 482},\n",
       "  {'loss': 0.750978946685791, 'step': 483},\n",
       "  {'loss': 0.16228926181793213, 'step': 484},\n",
       "  {'loss': 0.519422173500061, 'step': 485},\n",
       "  {'loss': 0.6093742847442627, 'step': 486},\n",
       "  {'loss': 0.515113115310669, 'step': 487},\n",
       "  {'loss': 0.29796352982521057, 'step': 488},\n",
       "  {'loss': 0.2864377200603485, 'step': 489},\n",
       "  {'loss': 0.7572245001792908, 'step': 490},\n",
       "  {'loss': 0.34095925092697144, 'step': 491},\n",
       "  {'loss': 0.28720977902412415, 'step': 492},\n",
       "  {'loss': 0.7373809814453125, 'step': 493},\n",
       "  {'loss': 0.4126114249229431, 'step': 494},\n",
       "  {'loss': 0.27741503715515137, 'step': 495},\n",
       "  {'loss': 0.4440594017505646, 'step': 496},\n",
       "  {'loss': 0.5831830501556396, 'step': 497},\n",
       "  {'loss': 0.2277582585811615, 'step': 498},\n",
       "  {'loss': 0.7901557683944702, 'step': 499},\n",
       "  {'loss': 0.31226634979248047, 'step': 500},\n",
       "  {'loss': 0.21150945127010345, 'step': 501},\n",
       "  {'loss': 0.4267484247684479, 'step': 502},\n",
       "  {'loss': 0.32135820388793945, 'step': 503},\n",
       "  {'loss': 0.5509992241859436, 'step': 504},\n",
       "  {'loss': 0.4759140610694885, 'step': 505},\n",
       "  {'loss': 0.5247995257377625, 'step': 506},\n",
       "  {'loss': 0.38977184891700745, 'step': 507},\n",
       "  {'loss': 0.40866219997406006, 'step': 508},\n",
       "  {'loss': 0.4208192527294159, 'step': 509},\n",
       "  {'loss': 0.4022977948188782, 'step': 510},\n",
       "  {'loss': 0.3976457715034485, 'step': 511},\n",
       "  {'loss': 0.5599077343940735, 'step': 512},\n",
       "  {'loss': 0.34683001041412354, 'step': 513},\n",
       "  {'loss': 0.3217986524105072, 'step': 514},\n",
       "  {'loss': 0.49771827459335327, 'step': 515},\n",
       "  {'loss': 0.6443846821784973, 'step': 516},\n",
       "  {'loss': 0.5695054531097412, 'step': 517},\n",
       "  {'loss': 0.6576389074325562, 'step': 518},\n",
       "  {'loss': 0.39212146401405334, 'step': 519},\n",
       "  {'loss': 0.3142791986465454, 'step': 520},\n",
       "  {'loss': 0.5712992548942566, 'step': 521},\n",
       "  {'loss': 0.4078424274921417, 'step': 522},\n",
       "  {'loss': 0.49990588426589966, 'step': 523},\n",
       "  {'loss': 0.49732881784439087, 'step': 524},\n",
       "  {'loss': 0.5630128383636475, 'step': 525},\n",
       "  {'loss': 0.5448774695396423, 'step': 526},\n",
       "  {'loss': 0.27059662342071533, 'step': 527},\n",
       "  {'loss': 0.5176059007644653, 'step': 528},\n",
       "  {'loss': 0.1198875829577446, 'step': 529},\n",
       "  {'loss': 0.18204845488071442, 'step': 530},\n",
       "  {'loss': 0.550237238407135, 'step': 531},\n",
       "  {'loss': 0.6152066588401794, 'step': 532},\n",
       "  {'loss': 0.2530815899372101, 'step': 533},\n",
       "  {'loss': 0.24775546789169312, 'step': 534},\n",
       "  {'loss': 1.0718618631362915, 'step': 535},\n",
       "  {'loss': 0.2990153133869171, 'step': 536},\n",
       "  {'loss': 0.9294218420982361, 'step': 537},\n",
       "  {'loss': 0.14100795984268188, 'step': 538},\n",
       "  {'loss': 0.2102714627981186, 'step': 539},\n",
       "  {'loss': 0.2708855867385864, 'step': 540},\n",
       "  {'loss': 0.22579599916934967, 'step': 541},\n",
       "  {'loss': 0.7689310312271118, 'step': 542},\n",
       "  {'loss': 0.6969188451766968, 'step': 543},\n",
       "  {'loss': 0.9204649925231934, 'step': 544},\n",
       "  {'loss': 1.19888436794281, 'step': 545},\n",
       "  {'loss': 0.4877653419971466, 'step': 546},\n",
       "  {'loss': 0.20131883025169373, 'step': 547},\n",
       "  {'loss': 0.4385114312171936, 'step': 548},\n",
       "  {'loss': 0.1616908311843872, 'step': 549},\n",
       "  {'loss': 0.21658656001091003, 'step': 550},\n",
       "  {'loss': 0.6790763139724731, 'step': 551},\n",
       "  {'loss': 0.29442575573921204, 'step': 552},\n",
       "  {'loss': 0.4449305236339569, 'step': 553},\n",
       "  {'loss': 1.3426909446716309, 'step': 554},\n",
       "  {'loss': 0.5994842648506165, 'step': 555},\n",
       "  {'loss': 0.38917216658592224, 'step': 556},\n",
       "  {'loss': 0.23506204783916473, 'step': 557},\n",
       "  {'loss': 0.4143940508365631, 'step': 558},\n",
       "  {'loss': 0.28730788826942444, 'step': 559},\n",
       "  {'loss': 0.14233572781085968, 'step': 560},\n",
       "  {'loss': 0.27315646409988403, 'step': 561},\n",
       "  {'loss': 0.06027605012059212, 'step': 562},\n",
       "  {'loss': 0.6117871403694153, 'step': 563},\n",
       "  {'loss': 0.41133928298950195, 'step': 564},\n",
       "  {'loss': 0.6174060106277466, 'step': 565},\n",
       "  {'loss': 0.30155059695243835, 'step': 566},\n",
       "  {'loss': 0.41494569182395935, 'step': 567},\n",
       "  {'loss': 0.48572415113449097, 'step': 568},\n",
       "  {'loss': 0.7144725322723389, 'step': 569},\n",
       "  {'loss': 0.26181793212890625, 'step': 570},\n",
       "  {'loss': 0.354474276304245, 'step': 571},\n",
       "  {'loss': 0.3991774022579193, 'step': 572},\n",
       "  {'loss': 0.35253986716270447, 'step': 573},\n",
       "  {'loss': 0.30951744318008423, 'step': 574},\n",
       "  {'loss': 0.49723848700523376, 'step': 575},\n",
       "  {'loss': 0.14339569211006165, 'step': 576},\n",
       "  {'loss': 0.2565351128578186, 'step': 577},\n",
       "  {'loss': 0.13672001659870148, 'step': 578},\n",
       "  {'loss': 0.26801836490631104, 'step': 579},\n",
       "  {'loss': 0.7976637482643127, 'step': 580},\n",
       "  {'loss': 0.6816115975379944, 'step': 581},\n",
       "  {'loss': 0.3867054283618927, 'step': 582},\n",
       "  {'loss': 0.16914387047290802, 'step': 583},\n",
       "  {'loss': 0.38236260414123535, 'step': 584},\n",
       "  {'loss': 0.4286275804042816, 'step': 585},\n",
       "  {'loss': 0.5169339179992676, 'step': 586},\n",
       "  {'loss': 0.3906390368938446, 'step': 587},\n",
       "  {'loss': 0.7587632536888123, 'step': 588},\n",
       "  {'loss': 0.7014504671096802, 'step': 589},\n",
       "  {'loss': 0.6195436716079712, 'step': 590},\n",
       "  {'loss': 0.9149954915046692, 'step': 591},\n",
       "  {'loss': 0.2038070410490036, 'step': 592},\n",
       "  {'loss': 0.6432379484176636, 'step': 593},\n",
       "  {'loss': 0.19250056147575378, 'step': 594},\n",
       "  {'loss': 0.8103479743003845, 'step': 595},\n",
       "  {'loss': 1.00118887424469, 'step': 596},\n",
       "  {'loss': 0.22320835292339325, 'step': 597},\n",
       "  {'loss': 0.3427407741546631, 'step': 598},\n",
       "  {'loss': 0.5923618674278259, 'step': 599},\n",
       "  {'loss': 0.588901162147522, 'step': 600},\n",
       "  {'loss': 0.7865927815437317, 'step': 601},\n",
       "  {'loss': 0.353892058134079, 'step': 602},\n",
       "  {'loss': 0.3308636248111725, 'step': 603},\n",
       "  {'loss': 0.18612024188041687, 'step': 604},\n",
       "  {'loss': 0.7491533756256104, 'step': 605},\n",
       "  {'loss': 0.6601560711860657, 'step': 606},\n",
       "  {'loss': 0.5760080218315125, 'step': 607},\n",
       "  {'loss': 0.2824575901031494, 'step': 608},\n",
       "  {'loss': 0.40097877383232117, 'step': 609},\n",
       "  {'loss': 0.6890290975570679, 'step': 610},\n",
       "  {'loss': 0.4560543894767761, 'step': 611},\n",
       "  {'loss': 0.3739047646522522, 'step': 612},\n",
       "  {'loss': 0.6809396147727966, 'step': 613},\n",
       "  {'loss': 0.6672056317329407, 'step': 614},\n",
       "  {'loss': 1.2621210813522339, 'step': 615},\n",
       "  {'loss': 0.7804372906684875, 'step': 616},\n",
       "  {'loss': 0.3280896842479706, 'step': 617},\n",
       "  {'loss': 10.540443420410156, 'step': 618},\n",
       "  {'loss': 0.26245254278182983, 'step': 619},\n",
       "  {'loss': 0.5507658123970032, 'step': 620},\n",
       "  {'loss': 1.2742290496826172, 'step': 621},\n",
       "  {'loss': 0.33968594670295715, 'step': 622},\n",
       "  {'loss': 0.32335636019706726, 'step': 623},\n",
       "  {'loss': 0.4741220772266388, 'step': 624},\n",
       "  {'loss': 0.5596286654472351, 'step': 625},\n",
       "  {'loss': 0.5133088827133179, 'step': 626},\n",
       "  {'loss': 0.32780247926712036, 'step': 627},\n",
       "  {'loss': 0.5889960527420044, 'step': 628},\n",
       "  {'loss': 0.6072545051574707, 'step': 629},\n",
       "  {'loss': 0.5668124556541443, 'step': 630},\n",
       "  {'loss': 0.5868969559669495, 'step': 631},\n",
       "  {'loss': 0.8197291493415833, 'step': 632},\n",
       "  {'loss': 0.3673568665981293, 'step': 633},\n",
       "  {'loss': 0.5911469459533691, 'step': 634},\n",
       "  {'loss': 0.3297934830188751, 'step': 635},\n",
       "  {'loss': 0.3710175156593323, 'step': 636},\n",
       "  {'loss': 0.748229444026947, 'step': 637},\n",
       "  {'loss': 0.41010695695877075, 'step': 638},\n",
       "  {'loss': 0.5680335164070129, 'step': 639},\n",
       "  {'loss': 0.6712290644645691, 'step': 640},\n",
       "  {'loss': 0.7209954261779785, 'step': 641},\n",
       "  {'loss': 0.40494465827941895, 'step': 642},\n",
       "  {'loss': 0.30488163232803345, 'step': 643},\n",
       "  {'loss': 0.4556775689125061, 'step': 644},\n",
       "  {'loss': 0.2879995107650757, 'step': 645},\n",
       "  {'loss': 0.21624425053596497, 'step': 646},\n",
       "  {'loss': 0.452999472618103, 'step': 647},\n",
       "  {'loss': 0.34092921018600464, 'step': 648},\n",
       "  {'loss': 0.362588107585907, 'step': 649},\n",
       "  {'loss': 1.1427408456802368, 'step': 650},\n",
       "  {'loss': 0.560620903968811, 'step': 651},\n",
       "  {'loss': 0.5125551819801331, 'step': 652},\n",
       "  {'loss': 0.4043416976928711, 'step': 653},\n",
       "  {'loss': 0.7354610562324524, 'step': 654},\n",
       "  {'loss': 0.3286136984825134, 'step': 655},\n",
       "  {'loss': 0.36085349321365356, 'step': 656},\n",
       "  {'loss': 0.5584760904312134, 'step': 657},\n",
       "  {'loss': 0.2942452132701874, 'step': 658},\n",
       "  {'loss': 0.950701117515564, 'step': 659},\n",
       "  {'loss': 0.40821680426597595, 'step': 660},\n",
       "  {'loss': 0.41936296224594116, 'step': 661},\n",
       "  {'loss': 0.16880635917186737, 'step': 662},\n",
       "  {'loss': 0.21446146070957184, 'step': 663},\n",
       "  {'loss': 1.4542135000228882, 'step': 664},\n",
       "  {'loss': 0.5604830980300903, 'step': 665},\n",
       "  {'loss': 0.869987964630127, 'step': 666},\n",
       "  {'loss': 0.4659423828125, 'step': 667},\n",
       "  {'loss': 0.3230903148651123, 'step': 668},\n",
       "  {'loss': 4.645468235015869, 'step': 669},\n",
       "  {'loss': 0.6814130544662476, 'step': 670},\n",
       "  {'loss': 0.39542487263679504, 'step': 671},\n",
       "  {'loss': 0.5609690546989441, 'step': 672},\n",
       "  {'loss': 0.48768097162246704, 'step': 673},\n",
       "  {'loss': 0.5529043674468994, 'step': 674},\n",
       "  {'loss': 0.16433189809322357, 'step': 675},\n",
       "  {'loss': 0.20591281354427338, 'step': 676},\n",
       "  {'loss': 0.15778636932373047, 'step': 677},\n",
       "  {'loss': 0.632850706577301, 'step': 678},\n",
       "  {'loss': 0.17901693284511566, 'step': 679},\n",
       "  {'loss': 0.40478813648223877, 'step': 680},\n",
       "  {'loss': 0.5166364908218384, 'step': 681},\n",
       "  {'loss': 0.6062000393867493, 'step': 682},\n",
       "  {'loss': 0.7038096785545349, 'step': 683},\n",
       "  {'loss': 0.46039366722106934, 'step': 684},\n",
       "  {'loss': 0.5609087347984314, 'step': 685},\n",
       "  {'loss': 0.32174718379974365, 'step': 686},\n",
       "  {'loss': 0.1673969328403473, 'step': 687},\n",
       "  {'loss': 0.49113067984580994, 'step': 688},\n",
       "  {'loss': 0.19541898369789124, 'step': 689},\n",
       "  {'loss': 0.9693871736526489, 'step': 690},\n",
       "  {'loss': 0.43696415424346924, 'step': 691},\n",
       "  {'loss': 0.45103776454925537, 'step': 692},\n",
       "  {'loss': 0.5571860671043396, 'step': 693},\n",
       "  {'loss': 0.34486672282218933, 'step': 694},\n",
       "  {'loss': 0.1843399703502655, 'step': 695},\n",
       "  {'loss': 0.3798292875289917, 'step': 696},\n",
       "  {'loss': 0.9774949550628662, 'step': 697},\n",
       "  {'loss': 0.2875094413757324, 'step': 698},\n",
       "  {'loss': 0.32624906301498413, 'step': 699},\n",
       "  {'loss': 0.29549142718315125, 'step': 700},\n",
       "  {'loss': 0.9081107378005981, 'step': 701},\n",
       "  {'loss': 0.5832610130310059, 'step': 702},\n",
       "  {'loss': 1.2015341520309448, 'step': 703},\n",
       "  {'loss': 0.37291419506073, 'step': 704},\n",
       "  {'loss': 0.4993737041950226, 'step': 705},\n",
       "  {'loss': 0.7338805794715881, 'step': 706},\n",
       "  {'loss': 0.6462448835372925, 'step': 707},\n",
       "  {'loss': 0.30893129110336304, 'step': 708},\n",
       "  {'loss': 0.23294101655483246, 'step': 709},\n",
       "  {'loss': 0.45501813292503357, 'step': 710},\n",
       "  {'loss': 0.1678762137889862, 'step': 711},\n",
       "  {'loss': 1.0857359170913696, 'step': 712},\n",
       "  {'loss': 1.2178062200546265, 'step': 713},\n",
       "  {'loss': 0.7601445913314819, 'step': 714},\n",
       "  {'loss': 0.2990444302558899, 'step': 715},\n",
       "  {'loss': 0.5365029573440552, 'step': 716},\n",
       "  {'loss': 0.10654672980308533, 'step': 717},\n",
       "  {'loss': 0.17201335728168488, 'step': 718},\n",
       "  {'loss': 0.5608389377593994, 'step': 719},\n",
       "  {'loss': 0.33819952607154846, 'step': 720},\n",
       "  {'loss': 0.4341970384120941, 'step': 721},\n",
       "  {'loss': 0.5240507125854492, 'step': 722},\n",
       "  {'loss': 0.20803597569465637, 'step': 723},\n",
       "  {'loss': 1.0604884624481201, 'step': 724},\n",
       "  {'loss': 0.48486194014549255, 'step': 725},\n",
       "  {'loss': 0.23576538264751434, 'step': 726},\n",
       "  {'loss': 0.40241098403930664, 'step': 727},\n",
       "  {'loss': 0.7695307731628418, 'step': 728},\n",
       "  {'loss': 0.3266896903514862, 'step': 729},\n",
       "  {'loss': 0.6038352251052856, 'step': 730},\n",
       "  {'loss': 0.37173232436180115, 'step': 731},\n",
       "  {'loss': 1.0479564666748047, 'step': 732},\n",
       "  {'loss': 0.47904232144355774, 'step': 733},\n",
       "  {'loss': 0.3939743936061859, 'step': 734},\n",
       "  {'loss': 0.7739316821098328, 'step': 735},\n",
       "  {'loss': 0.7080278992652893, 'step': 736},\n",
       "  {'loss': 0.3696102797985077, 'step': 737},\n",
       "  {'loss': 0.2968222498893738, 'step': 738},\n",
       "  {'loss': 0.22930851578712463, 'step': 739},\n",
       "  {'loss': 0.2030041217803955, 'step': 740},\n",
       "  {'loss': 1.4699220657348633, 'step': 741},\n",
       "  {'loss': 0.2684668004512787, 'step': 742},\n",
       "  {'loss': 0.6011741161346436, 'step': 743},\n",
       "  {'loss': 0.3819076418876648, 'step': 744},\n",
       "  {'loss': 0.3554103672504425, 'step': 745},\n",
       "  {'loss': 0.2436116635799408, 'step': 746},\n",
       "  {'loss': 0.2233264148235321, 'step': 747},\n",
       "  {'loss': 0.3448371887207031, 'step': 748},\n",
       "  {'loss': 0.463581383228302, 'step': 749},\n",
       "  {'loss': 0.22208449244499207, 'step': 750},\n",
       "  {'loss': 0.5493006706237793, 'step': 751},\n",
       "  {'loss': 0.6854101419448853, 'step': 752},\n",
       "  {'loss': 0.364292711019516, 'step': 753},\n",
       "  {'loss': 0.4085928201675415, 'step': 754},\n",
       "  {'loss': 0.5947015285491943, 'step': 755},\n",
       "  {'loss': 0.45440053939819336, 'step': 756},\n",
       "  {'loss': 0.27704381942749023, 'step': 757},\n",
       "  {'loss': 0.20274704694747925, 'step': 758},\n",
       "  {'loss': 0.5188958644866943, 'step': 759},\n",
       "  {'loss': 0.45764246582984924, 'step': 760},\n",
       "  {'loss': 0.5594679117202759, 'step': 761},\n",
       "  {'loss': 0.5483714938163757, 'step': 762},\n",
       "  {'loss': 0.7931938767433167, 'step': 763},\n",
       "  {'loss': 0.5284171104431152, 'step': 764},\n",
       "  {'loss': 0.58185875415802, 'step': 765},\n",
       "  {'loss': 0.5781707167625427, 'step': 766},\n",
       "  {'loss': 0.37124893069267273, 'step': 767},\n",
       "  {'loss': 0.4519471526145935, 'step': 768},\n",
       "  {'loss': 0.3074333965778351, 'step': 769},\n",
       "  {'loss': 0.8573207855224609, 'step': 770},\n",
       "  {'loss': 0.4351279139518738, 'step': 771},\n",
       "  {'loss': 0.18842259049415588, 'step': 772},\n",
       "  {'loss': 0.607532262802124, 'step': 773},\n",
       "  {'loss': 1.3815511465072632, 'step': 774},\n",
       "  {'loss': 0.5800700783729553, 'step': 775},\n",
       "  {'loss': 0.47867894172668457, 'step': 776},\n",
       "  {'loss': 0.44804060459136963, 'step': 777},\n",
       "  {'loss': 0.19763869047164917, 'step': 778},\n",
       "  {'loss': 0.5887026786804199, 'step': 779},\n",
       "  {'loss': 0.318685919046402, 'step': 780},\n",
       "  {'loss': 0.32052046060562134, 'step': 781},\n",
       "  {'loss': 0.33565235137939453, 'step': 782},\n",
       "  {'loss': 0.16554048657417297, 'step': 783},\n",
       "  {'loss': 0.43118298053741455, 'step': 784},\n",
       "  {'loss': 0.3806067109107971, 'step': 785},\n",
       "  {'loss': 0.25159305334091187, 'step': 786},\n",
       "  {'loss': 0.2606475055217743, 'step': 787},\n",
       "  {'loss': 0.7660032510757446, 'step': 788},\n",
       "  {'loss': 0.8504729866981506, 'step': 789},\n",
       "  {'loss': 0.36095887422561646, 'step': 790},\n",
       "  {'loss': 0.15973079204559326, 'step': 791},\n",
       "  {'loss': 0.31309208273887634, 'step': 792},\n",
       "  {'loss': 0.7278610467910767, 'step': 793},\n",
       "  {'loss': 0.5293790698051453, 'step': 794},\n",
       "  {'loss': 0.5229412317276001, 'step': 795},\n",
       "  {'loss': 0.6882257461547852, 'step': 796},\n",
       "  {'loss': 0.18323086202144623, 'step': 797},\n",
       "  {'loss': 0.2022853046655655, 'step': 798},\n",
       "  {'loss': 0.10641026496887207, 'step': 799},\n",
       "  {'loss': 0.26224398612976074, 'step': 800},\n",
       "  {'loss': 0.8106250762939453, 'step': 801},\n",
       "  {'loss': 0.24738319218158722, 'step': 802},\n",
       "  {'loss': 1.133755087852478, 'step': 803},\n",
       "  {'loss': 0.9836841821670532, 'step': 804},\n",
       "  {'loss': 0.6666441559791565, 'step': 805},\n",
       "  {'loss': 0.5813857316970825, 'step': 806},\n",
       "  {'loss': 0.40430858731269836, 'step': 807},\n",
       "  {'loss': 0.22320854663848877, 'step': 808},\n",
       "  {'loss': 0.8739340901374817, 'step': 809},\n",
       "  {'loss': 0.39053618907928467, 'step': 810},\n",
       "  {'loss': 0.9535667300224304, 'step': 811},\n",
       "  {'loss': 0.4142928421497345, 'step': 812},\n",
       "  {'loss': 0.9728960394859314, 'step': 813},\n",
       "  {'loss': 1.0634765625, 'step': 814},\n",
       "  {'loss': 0.18083804845809937, 'step': 815},\n",
       "  {'loss': 0.46384966373443604, 'step': 816},\n",
       "  {'loss': 0.36787715554237366, 'step': 817},\n",
       "  {'loss': 0.38736945390701294, 'step': 818},\n",
       "  {'loss': 0.429418683052063, 'step': 819},\n",
       "  {'loss': 1.3088593482971191, 'step': 820},\n",
       "  {'loss': 0.28936606645584106, 'step': 821},\n",
       "  {'loss': 0.35712730884552, 'step': 822},\n",
       "  {'loss': 0.3090677559375763, 'step': 823},\n",
       "  {'loss': 0.3475628197193146, 'step': 824},\n",
       "  {'loss': 1.3415032625198364, 'step': 825},\n",
       "  {'loss': 1.641925573348999, 'step': 826},\n",
       "  {'loss': 0.3638457655906677, 'step': 827},\n",
       "  {'loss': 0.5141481161117554, 'step': 828},\n",
       "  {'loss': 0.30052635073661804, 'step': 829},\n",
       "  {'loss': 0.803125262260437, 'step': 830},\n",
       "  {'loss': 1.4457403421401978, 'step': 831},\n",
       "  {'loss': 0.16617225110530853, 'step': 832},\n",
       "  {'loss': 0.2996091842651367, 'step': 833},\n",
       "  {'loss': 0.44599923491477966, 'step': 834},\n",
       "  {'loss': 0.2774101197719574, 'step': 835},\n",
       "  {'loss': 0.5660258531570435, 'step': 836},\n",
       "  {'loss': 0.442721962928772, 'step': 837},\n",
       "  {'loss': 0.7078101634979248, 'step': 838},\n",
       "  {'loss': 0.7511588931083679, 'step': 839},\n",
       "  {'loss': 0.2278824895620346, 'step': 840},\n",
       "  {'loss': 0.48373907804489136, 'step': 841},\n",
       "  {'loss': 0.6757068037986755, 'step': 842},\n",
       "  {'loss': 0.23029987514019012, 'step': 843},\n",
       "  {'loss': 0.5443607568740845, 'step': 844},\n",
       "  {'loss': 0.8700096607208252, 'step': 845},\n",
       "  {'loss': 0.11481086164712906, 'step': 846},\n",
       "  {'loss': 0.4261903762817383, 'step': 847},\n",
       "  {'loss': 0.35633084177970886, 'step': 848},\n",
       "  {'loss': 0.9312456846237183, 'step': 849},\n",
       "  {'loss': 1.1714329719543457, 'step': 850},\n",
       "  {'loss': 0.18070827424526215, 'step': 851},\n",
       "  {'loss': 41.43863296508789, 'step': 852},\n",
       "  {'loss': 0.18801233172416687, 'step': 853},\n",
       "  {'loss': 1.1191260814666748, 'step': 854},\n",
       "  {'loss': 0.6678796410560608, 'step': 855},\n",
       "  {'loss': 0.29378628730773926, 'step': 856},\n",
       "  {'loss': 0.303715318441391, 'step': 857},\n",
       "  {'loss': 0.32594165205955505, 'step': 858},\n",
       "  {'loss': 0.440964013338089, 'step': 859},\n",
       "  {'loss': 0.7659255862236023, 'step': 860},\n",
       "  {'loss': 0.4659236669540405, 'step': 861},\n",
       "  {'loss': 0.6359593272209167, 'step': 862},\n",
       "  {'loss': 0.6803382039070129, 'step': 863},\n",
       "  {'loss': 1.5729219913482666, 'step': 864},\n",
       "  {'loss': 0.8436311483383179, 'step': 865},\n",
       "  {'loss': 0.777725875377655, 'step': 866},\n",
       "  {'loss': 0.1406339704990387, 'step': 867},\n",
       "  {'loss': 0.7851399779319763, 'step': 868},\n",
       "  {'loss': 1.0499807596206665, 'step': 869},\n",
       "  {'loss': 0.5324927568435669, 'step': 870},\n",
       "  {'loss': 0.25403866171836853, 'step': 871},\n",
       "  {'loss': 0.9389770030975342, 'step': 872},\n",
       "  {'loss': 0.7086617946624756, 'step': 873},\n",
       "  {'loss': 0.44343996047973633, 'step': 874},\n",
       "  {'loss': 0.4902869760990143, 'step': 875},\n",
       "  {'loss': 0.41690289974212646, 'step': 876},\n",
       "  {'loss': 0.6683169007301331, 'step': 877},\n",
       "  {'loss': 0.2368486523628235, 'step': 878},\n",
       "  {'loss': 0.3019423484802246, 'step': 879},\n",
       "  {'loss': 0.3971112072467804, 'step': 880},\n",
       "  {'loss': 0.24940679967403412, 'step': 881},\n",
       "  {'loss': 0.2382199764251709, 'step': 882},\n",
       "  {'loss': 0.266391396522522, 'step': 883},\n",
       "  {'loss': 0.18595987558364868, 'step': 884},\n",
       "  {'loss': 0.3322877883911133, 'step': 885},\n",
       "  {'loss': 0.4287416934967041, 'step': 886},\n",
       "  {'loss': 0.1523171067237854, 'step': 887},\n",
       "  {'loss': 1.9321480989456177, 'step': 888},\n",
       "  {'loss': 0.3321079611778259, 'step': 889},\n",
       "  {'loss': 0.25997838377952576, 'step': 890},\n",
       "  {'loss': 0.24503469467163086, 'step': 891},\n",
       "  {'loss': 1.0206928253173828, 'step': 892},\n",
       "  {'loss': 0.34003984928131104, 'step': 893},\n",
       "  {'loss': 0.20427244901657104, 'step': 894},\n",
       "  {'loss': 1.032650113105774, 'step': 895},\n",
       "  {'loss': 0.6496759653091431, 'step': 896},\n",
       "  {'loss': 0.3366590738296509, 'step': 897},\n",
       "  {'loss': 0.6104829907417297, 'step': 898},\n",
       "  {'loss': 0.7679861783981323, 'step': 899},\n",
       "  {'loss': 0.2252100706100464, 'step': 900},\n",
       "  {'loss': 0.9617820978164673, 'step': 901},\n",
       "  {'loss': 0.46859806776046753, 'step': 902},\n",
       "  {'loss': 0.18272896111011505, 'step': 903},\n",
       "  {'loss': 0.6176851391792297, 'step': 904},\n",
       "  {'loss': 0.7196404933929443, 'step': 905},\n",
       "  {'loss': 0.4629938304424286, 'step': 906},\n",
       "  {'loss': 0.594525933265686, 'step': 907},\n",
       "  {'loss': 0.6565828323364258, 'step': 908},\n",
       "  {'loss': 0.2884945273399353, 'step': 909},\n",
       "  {'loss': 0.46513912081718445, 'step': 910},\n",
       "  {'loss': 0.3543926477432251, 'step': 911},\n",
       "  {'loss': 0.25375282764434814, 'step': 912},\n",
       "  {'loss': 0.31554844975471497, 'step': 913},\n",
       "  {'loss': 0.6146427392959595, 'step': 914},\n",
       "  {'loss': 0.8636297583580017, 'step': 915},\n",
       "  {'loss': 1.293522834777832, 'step': 916},\n",
       "  {'loss': 0.3114616274833679, 'step': 917},\n",
       "  {'loss': 0.3485037088394165, 'step': 918},\n",
       "  {'loss': 0.8255005478858948, 'step': 919},\n",
       "  {'loss': 0.25091230869293213, 'step': 920},\n",
       "  {'loss': 0.8590202927589417, 'step': 921},\n",
       "  {'loss': 0.6615907549858093, 'step': 922},\n",
       "  {'loss': 0.836067795753479, 'step': 923},\n",
       "  {'loss': 0.16136625409126282, 'step': 924},\n",
       "  {'loss': 0.3180158734321594, 'step': 925},\n",
       "  {'loss': 0.5848120450973511, 'step': 926},\n",
       "  {'loss': 0.14996427297592163, 'step': 927},\n",
       "  {'loss': 0.22234030067920685, 'step': 928},\n",
       "  {'loss': 0.33577901124954224, 'step': 929},\n",
       "  {'loss': 0.4539002776145935, 'step': 930},\n",
       "  {'loss': 0.45130082964897156, 'step': 931},\n",
       "  {'loss': 1.0181758403778076, 'step': 932},\n",
       "  {'loss': 0.39593496918678284, 'step': 933},\n",
       "  {'loss': 0.49230286478996277, 'step': 934},\n",
       "  {'loss': 0.3278355002403259, 'step': 935},\n",
       "  {'loss': 1.1397862434387207, 'step': 936},\n",
       "  {'loss': 0.27106964588165283, 'step': 937},\n",
       "  {'loss': 0.7983195781707764, 'step': 938},\n",
       "  {'loss': 0.20154260098934174, 'step': 939},\n",
       "  {'loss': 1.2354656457901, 'step': 940},\n",
       "  {'loss': 0.3214104175567627, 'step': 941},\n",
       "  {'loss': 0.23784752190113068, 'step': 942},\n",
       "  {'loss': 0.6205726265907288, 'step': 943},\n",
       "  {'loss': 0.8640063405036926, 'step': 944},\n",
       "  {'loss': 0.34163835644721985, 'step': 945},\n",
       "  {'loss': 0.40475478768348694, 'step': 946},\n",
       "  {'loss': 0.5525254607200623, 'step': 947},\n",
       "  {'loss': 0.3351938724517822, 'step': 948},\n",
       "  {'loss': 0.31511449813842773, 'step': 949},\n",
       "  {'loss': 0.4401637613773346, 'step': 950},\n",
       "  {'loss': 0.4094379246234894, 'step': 951},\n",
       "  {'loss': 0.5370713472366333, 'step': 952},\n",
       "  {'loss': 0.6775140762329102, 'step': 953},\n",
       "  {'loss': 0.6887717843055725, 'step': 954},\n",
       "  {'loss': 0.18698400259017944, 'step': 955},\n",
       "  {'loss': 0.18164515495300293, 'step': 956},\n",
       "  {'loss': 0.504637598991394, 'step': 957},\n",
       "  {'loss': 0.6627600193023682, 'step': 958},\n",
       "  {'loss': 0.25633499026298523, 'step': 959},\n",
       "  {'loss': 0.9551422595977783, 'step': 960},\n",
       "  {'loss': 1.0723209381103516, 'step': 961},\n",
       "  {'loss': 0.5475477576255798, 'step': 962},\n",
       "  {'loss': 0.697762131690979, 'step': 963},\n",
       "  {'loss': 0.16941455006599426, 'step': 964},\n",
       "  {'loss': 0.3451124429702759, 'step': 965},\n",
       "  {'loss': 0.5493192076683044, 'step': 966},\n",
       "  {'loss': 0.334136962890625, 'step': 967},\n",
       "  {'loss': 0.14860183000564575, 'step': 968},\n",
       "  {'loss': 0.48081865906715393, 'step': 969},\n",
       "  {'loss': 0.2635459899902344, 'step': 970},\n",
       "  {'loss': 0.7350450754165649, 'step': 971},\n",
       "  {'loss': 0.3404972553253174, 'step': 972},\n",
       "  {'loss': 0.5514989495277405, 'step': 973},\n",
       "  {'loss': 0.7161194682121277, 'step': 974},\n",
       "  {'loss': 0.30577948689460754, 'step': 975},\n",
       "  {'loss': 0.3201269507408142, 'step': 976},\n",
       "  {'loss': 0.46459633111953735, 'step': 977},\n",
       "  {'loss': 0.6494007706642151, 'step': 978},\n",
       "  {'loss': 0.43768495321273804, 'step': 979},\n",
       "  {'loss': 0.7114545702934265, 'step': 980},\n",
       "  {'loss': 0.5563763380050659, 'step': 981},\n",
       "  {'loss': 0.6339962482452393, 'step': 982},\n",
       "  {'loss': 1.6792831420898438, 'step': 983},\n",
       "  {'loss': 0.6466259360313416, 'step': 984},\n",
       "  {'loss': 0.6855974197387695, 'step': 985},\n",
       "  {'loss': 0.42504721879959106, 'step': 986},\n",
       "  {'loss': 0.3832934498786926, 'step': 987},\n",
       "  {'loss': 0.5269062519073486, 'step': 988},\n",
       "  {'loss': 1.339961051940918, 'step': 989},\n",
       "  {'loss': 0.42893174290657043, 'step': 990},\n",
       "  {'loss': 0.4831477403640747, 'step': 991},\n",
       "  {'loss': 0.567922830581665, 'step': 992},\n",
       "  {'loss': 0.6878772974014282, 'step': 993},\n",
       "  {'loss': 0.4683595597743988, 'step': 994},\n",
       "  {'loss': 0.4877573549747467, 'step': 995},\n",
       "  {'loss': 0.38873398303985596, 'step': 996},\n",
       "  {'loss': 0.9452968239784241, 'step': 997},\n",
       "  {'loss': 0.8260958790779114, 'step': 998},\n",
       "  {'loss': 0.26759570837020874, 'step': 999},\n",
       "  ...],\n",
       " 'val': [{'loss': 6.808953506887452, 'step': 0},\n",
       "  {'loss': 0.5799678048688518, 'step': 726},\n",
       "  {'loss': 0.4611566014403154, 'step': 1452},\n",
       "  {'loss': 0.4913637350536575, 'step': 2178},\n",
       "  {'loss': 0.42231506047662626, 'step': 2904},\n",
       "  {'loss': 0.40502876951551636, 'step': 3630},\n",
       "  {'loss': 0.4004549472785193, 'step': 4356},\n",
       "  {'loss': 0.39465036314011603, 'step': 5082},\n",
       "  {'loss': 0.39547936482862994, 'step': 5808},\n",
       "  {'loss': 0.38369998382019604, 'step': 6534},\n",
       "  {'loss': 0.3862133692672923, 'step': 7260},\n",
       "  {'loss': 0.3837393260722564, 'step': 7986},\n",
       "  {'loss': 0.38117769289730996, 'step': 8712},\n",
       "  {'loss': 0.3757491785386377, 'step': 9438},\n",
       "  {'loss': 0.3745800651733048, 'step': 10164},\n",
       "  {'loss': 0.3755604223894679, 'step': 10890},\n",
       "  {'loss': 0.38106172781222125, 'step': 11616},\n",
       "  {'loss': 0.3615489130731949, 'step': 12342},\n",
       "  {'loss': 0.3606945588137985, 'step': 13068},\n",
       "  {'loss': 0.36392720317668165, 'step': 13794},\n",
       "  {'loss': 0.3568935002669815, 'step': 14520},\n",
       "  {'loss': 0.3536498037374709, 'step': 15246},\n",
       "  {'loss': 0.35456820094018926, 'step': 15972},\n",
       "  {'loss': 0.34497831170716564, 'step': 16698},\n",
       "  {'loss': 0.35340353389355267, 'step': 17424},\n",
       "  {'loss': 0.3514033544131301, 'step': 18150},\n",
       "  {'loss': 0.34335125405495326, 'step': 18876},\n",
       "  {'loss': 1.6540167899263545, 'step': 19602},\n",
       "  {'loss': 0.3636921441628913, 'step': 20328},\n",
       "  {'loss': 0.34469276257167175, 'step': 21054},\n",
       "  {'loss': 0.3343736356786214, 'step': 21780},\n",
       "  {'loss': 0.33509299984155605, 'step': 22506},\n",
       "  {'loss': 0.3379295765276044, 'step': 23232},\n",
       "  {'loss': 0.3437402593510703, 'step': 23958},\n",
       "  {'loss': 0.3468212978375598, 'step': 24684},\n",
       "  {'loss': 0.3276773308796331, 'step': 25410},\n",
       "  {'loss': 0.32887546759683733, 'step': 26136},\n",
       "  {'loss': 0.3287985077635808, 'step': 26862},\n",
       "  {'loss': 0.33313137379067004, 'step': 27588},\n",
       "  {'loss': 0.42269289016354183, 'step': 28314},\n",
       "  {'loss': 0.34086165680311437, 'step': 29040},\n",
       "  {'loss': 0.3277399886153207, 'step': 29766},\n",
       "  {'loss': 0.32942923966579696, 'step': 30492},\n",
       "  {'loss': 0.3491104126961763, 'step': 31218},\n",
       "  {'loss': 0.3290418210046843, 'step': 31944},\n",
       "  {'loss': 0.3414119782988444, 'step': 32670}]}"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 16
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T15:53:09.736056Z",
     "start_time": "2025-02-25T15:53:09.523003Z"
    }
   },
   "source": [
    "#画线要注意的是损失是不一定在零到1之间的\n",
    "def plot_learning_curves(record_dict, sample_step=500):\n",
    "    # build DataFrame\n",
    "    train_df = pd.DataFrame(record_dict[\"train\"]).set_index(\"step\").iloc[::sample_step]\n",
    "    val_df = pd.DataFrame(record_dict[\"val\"]).set_index(\"step\")\n",
    "\n",
    "    # plot\n",
    "    for idx, item in enumerate(train_df.columns):\n",
    "        plt.plot(train_df.index, train_df[item], label=f\"train_{item}\")\n",
    "        plt.plot(val_df.index, val_df[item], label=f\"val_{item}\")\n",
    "        plt.grid()\n",
    "        plt.legend()\n",
    "        # plt.xticks(range(0, train_df.index[-1], 10*sample_step), range(0, train_df.index[-1], 10*sample_step))\n",
    "        plt.xlabel(\"step\")\n",
    "\n",
    "        plt.show()\n",
    "\n",
    "plot_learning_curves(record)  #横坐标是 steps"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAhYAAAGwCAYAAAD16iy9AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAY/RJREFUeJzt3QeYU1XaB/B/kslUZihDGcrQe2+igIsoRUBdsa+y9i6uhV1X0VXB/rmuva4NG6KioEtRkN6b9N6HMpShzDA9k9zveU9yQyaZTtrc/H/Pc59MyWRuTpJ73/ue95xj0jRNAxEREZEfmP3xIERERESCgQURERH5DQMLIiIi8hsGFkREROQ3DCyIiIjIbxhYEBERkd8wsCAiIiK/iUKQORwOHD58GImJiTCZTMH+90RERFQFMu3VmTNn0KhRI5jN5vAJLCSoSE1NDfa/JSIiIj84cOAAmjRpEj6BhWQq9B1LSkry2+PabDbMmjULQ4cOhdVq9dvjVmdsE19sE19sE19sE19sE1+R1iZZWVkqMaCfx8MmsNC7PySo8HdgER8frx4zEl7gimCb+GKb+GKb+GKb+GKb+IrUNjGVU8bA4k0iIiLym0oFFs2bN1eRivc2evRo/+0RERERVVuV6gpZtWoV7Ha7+/tNmzZhyJAhuO666wKxb0RERGTkwKJevXrFvn/llVfQqlUrXHTRRaX+TUFBgdo8iz/0vinZ/EV/LH8+ZnXHNvHFNvHFNvHFNql8m8hUAvI7GZIYKYqKihAVFYXs7Gx1W52ZTCb1HCwWS6n3qejnwaRV8V1QWFioxrKOGTMGTz75ZKn3GzduHMaPH+/z84kTJ6qiFyIiqt7kZFS3bt2IKmA0IofDoeapkK0kubm5uOmmm5CZmVnm4IsqBxbff/+9+gdpaWkqwKhMxkKGq2RkZPh9VMjs2bNV1wzf3E5sE19sE19sE19sk4q3iZxCDh06pK7eGzZsWObESUYjzz0nJwcJCQnVfsJHTdNU4HD8+HF1bm7QoIHPfeT8LQFkeYFFlXM3n376KYYPH15mUCFiYmLU5k3emIH4wAbqcasztokvtokvtokvtkn5bSIBR35+vjoX1KhRA5FE7/6Ji4szRECVkJCgnsexY8dUkOjdLVLRz0KVAov9+/fj999/x08//VSVPyciIoPQC/qjo6NDvSvkB3qJggRMZdVblKVKIdbnn3+O+vXr47LLLqvSPyUiImOp7l0B5L/X0VyV1I8EFrfeemu1r4IlIiIi/6p0YCFdIFKweccdd/h5V4iIiCjiAgtZbEWqR9u2bRuYPSIiIqpGWrZsiTfffNMvjzV//nzVHXH69GlUV8bpyzhzBPEFxwB7oZSuhnpviIgojA0cOBDdu3f3S0CwYsWKclf8jCSGCSyiPrkIQ3JPwHbhBUCjLqHeHSIiqsYkMy8jXipSSyizUhthuKm/GKclLK65MoryQ70nREQRS020VFgUkq2i8z3edtttWLBgAd566y33YpoTJkxQtzNnzkSvXr3U/EuLFy/G7t27ceWVV6oJo2SejvPOO0/VGpbVFWIymfDJJ5/gqquuUsM327Rpg19++aXKbfrjjz+iU6dOap9kMdD//Oc/xX7//vvvq/8RGxur9vPaa691/27y5Mno0qWLmmsjOTkZgwcPVpN6BZJhMhawxqobEwMLIqKQybPZ0fGZ30Lyv7c8dynio8s/rUlAsWPHDnTu3BnPPfec+tnmzZvV7RNPPIHXXntNBQu1a9fGgQMHMGLECLz44ovqxP7ll1/iiiuuwPbt29GkSZNS/8f48ePx6quv4t///jfeeecdjBo1Ss0BVadOnUo9pzVr1uD6669Xy2PccMMNWLp0KR544AEVJEiAtHr1ajz00EP46quv0K9fP5w8eRKLFi1Sf5ueno4bb7xR7YcEOTJVt/wu0Ou5GCewiHIGFig6O304ERGRt5o1a6oJvSSbkJKSon62bds2dSuBhkxbrpNAoFu3bu7vn3/+eUyZMkVlIOQEX5rbbrtNndTFSy+9hLfffhsrV67EsGHDKrWvr7/+OgYNGoSnn35afS8DJ7Zs2aICFvkfMkpTZsy8/PLLVZ1Hs2bN0KNHD3dgIVOtX3311ernQrIXgWaYwEKzxEBN68GMBRFRyMRZLSpzEKr/fa569+5d7HtZuVSyBdOnT3efqPPy8tQJvSxdu3Z1fy0nfllbQ6bKrqytW7eqrhhP/fv3V10vUgMiQZAEDZJhkaBFNr0LRgIiCUokmLj00kvVqE7pJpFMTCCZjdYVwowFEVHoSH2BdEeEYvPHrJESBHj6xz/+oTIUknWQboR169apE7Ws8F0Wq9foRNk3mWDS3yRL8ccff+Dbb79V63s888wzKqCQ4aoyJbcsHCd1Ix07dlRdMu3atcPevXsRSGbjdYUwY0FERGWTrhB9nZOyLFmyRHU5SBZAAgrpOtm3bx+CpUOHDmofvPdJukT0tTxk5IoUZUotxYYNG9T+zZ071x3QSIZDaj7Wrl2rnrcESoFkmK4QjgohIqKKktEVMv+EnIRltEdp2QQZbSELbkrBppykpdYhEJmH0vz9739XI1GktkOKN5ctW4Z3331XjQQR06ZNw549ezBgwADVxTFjxgy1f5KZkOc3Z84c1QUi63vJ97IsugQrgWSgjIUzsDCxK4SIiMohXRxyxS9dBDIPRWk1E1I8KSdsGXEhwYXUKvTs2TNo+9mzZ098//33mDRpkhrFIl0dUmAqWRRRq1YtFfhccsklKmD48MMPVbeIDE+Vuo6FCxeqUS2S4fjXv/6lhqoOHz48oPtsnIyFNc55y4wFERGVQ060cvXvST9Ze2c29G4F3ejRo9WtnrmQjIHnBFlaCcM5KzpFt8wI6v3311xzjdpKcuGFF6ppwEsigcavv/6KYDMbaVSIwsCCiIgoZAwTWHAeCyIiCnf33XefqukoaZPfGUGU0WosmLEgIqJw9dxzz6n6jpJITYQRGCiwYMaCiIjCW/369dVmZIbrCuFaIURERKFjoMCCXSFEREShZsDAgl0hREREoWKYwEKL0uexYGBBREQUKgbMWOSFek+IiIgilgEDC2YsiIgosGRGzrfeeqtC9zWZTJg6dSoihQFHhTCwICIiChXDBRbsCiEiIgodAwUW7AohIgo5WUCrMCc0WwmLf5Xkv//9Lxo1auSz/PmVV16JO+64A7t371ZfN2jQQE21LcuW//77735roo0bN6rVSOPi4pCcnIx77rkH2dnZ7t/LomJ9+vRBQkKCWr20f//+2L9/v/rd+vXrcfHFFyMxMVHN1NmrVy+sXr0a4cQwM29qesbCzsCCiChkbLnAS41C87+fPAxEJ5R7t+uuuw5/+9vfMG/ePAwaNEj97OTJk2ol0BkzZqiTvCw1/uKLLyImJgZffvmlWjJ9+/btaNq06TntYk5Ojlp6vW/fvli1ahWOHTuGu+66Cw8++CAmTJiAoqIijBw5Enfffbda/rywsBArV65UdRpi1KhR6NGjBz744AO17Pu6detgtVoRTqKM1xXCCbKIiKh0tWvXxvDhwzFx4kR3YDF58mTUrVtXZQNkCfRu3bq57//8889jypQp+OWXX1QAcC4mTpyI/Px8FaxIRkK8++67KnD5v//7PxUkZGZm4vLLL0erVq3cy5/r0tLS8Nhjj6F9+/bq+zZt2iDcGC+wsDGwICIKGWu8M3MQqv9dQXLlL1mB999/X2UlvvnmG/zlL39RQYVkLMaNG4fp06cjPT1dZRHy8vLUSf1cbd26VQUtelAhpKtDumUkIzJgwADcdtttKqsxZMgQDB48GNdffz0aNmyo7jtmzBiV4fjqq6/U7yT7ogcg4cJwNRYmhw1w2EO9N0REkUlS9tIdEYrN1V1QEZIh0DRNBQ8HDhzAokWLVLAhZPVRyVC89NJL6ufS3dClSxfVLREMn3/+OZYtW4Z+/frhu+++Q9u2bbF8+XL1Owl4Nm/ejMsuuwxz585Fx44d1b6GE8MFFgoLOImIqAyxsbG4+uqrVaZCahnatWuHnj17qt8tWbJEZQ2uuuoqFVCkpKRg3759fvm/HTp0UAWYUmuhk/8nmRLZB53UUYwdOxZLly5F586dVReKTgKNRx99FLNmzVLPQQKRcGI2XFeIYJ0FERGVQzIUkrH47LPP3NkKvW7hp59+UpkKCQJuuukmnxEk5/I/Y2Njceutt2LTpk2qgFQKSW+++WY1CmXv3r0qoJCMhYwEkeBh586dKiCR7hip8ZBRI/I7CUikANSzBiMcGKfGwhwFBywww87AgoiIyiVDPuvUqaNqGyR40L3++utq2Kl0RUhB5+OPP46srCy//M/4+Hj89ttvePjhh9UwVvn+mmuuUf9T//22bdvwxRdf4MSJE6q2YvTo0bj33ntVrYf87JZbbsHRo0fVvknGYvz48QgnxgksADjMVpilvoKBBRERlUO6Hw4fPlzidN1Sv+BJTu6epGtEshgVCTg0r/k1pHvF+/F1krUorWYiOjpadduEO+N0hcgUFmbXWF7WWBAREYWEsQILkx5YMGNBRESB9/3336sZMGWGTu+tU6dOiESG6wpROJcFEREFgUy0NXDgQNWt4s0aZjNiBouhAgu7Kdr5BTMWREQUBLJmR+PGjUsMLCKV2ZAZC9ZYEBEFlXeBIlVP/hhWa6yMhTuwYMaCiCgYJN0vC2QdP34c9erVcy+WFSknYZmNU9b+qO4ZC03T1HOR11Gei4xAqSpDBRYOFm8SEQWVrLDZpEkTHDx40G+zU1ank7FMWiXLnxsloIqPj1cruJ5LoFTpwOLQoUNqspCZM2ciNzcXrVu3VtOJ9u7dG6HGjAURUfDJCAiZrdJmsyGSyPNduHChWjjMCIWaFosFUVFR5xwkVSqwOHXqlFqFTZaVlcBC0l4y1agsQRtexZussSAiCvZJSbZIIs9XZsOUKbqNEFj4S6UCC1krPjU1tdiCJy1atCjzbwoKCtSm02cpk0jPn9GtPJZevGkvyIYjwiLnkujtG2lXEWVhm/him/him/him/iKtDaxVfB5mrRKlPLK8qyyRrz0pS1YsEANsXnggQfUmvalkSVeS5rHXFZqk74cf+qa9jlanJiHrSlXY0fDkX59bCIiokiWm5ur1lTJzMxUk4L5JbCQdI8YM2YMrrvuOrWqmiyk8uGHH6qV2iqasZCsR0ZGRpk7VpVIKv3zW9Hq+CzY+z0Cx8X/QqSTNpk9ezaGDBnCNJ0L28QX28QX28QX28RXpLVJVlaWWvisvMAiqrJDa6RI86WXXnKvFy/LvpYVWMTExKjNm7wI/n4h7GZnjYXFYYMlAl7kigpEW1d3bBNfbBNfbBNfbJPIbRNrBZ9jpcaTyPKt0h3iSdaBT0tLQ3gNN80L9a4QERFFpEoFFjIiRNat97Rjxw40a9YM4YCrmxIREVWjwOLRRx/F8uXLVVfIrl27VAHmf//7X5916kOFE2QRERFVo8DivPPOw5QpU/Dtt9+ic+fOeP755/Hmm29i1KhRCAd6jQUzFkRERKFR6Zk3L7/8crWFI3fGwsYaCyIiolCo3qumeGGNBRERUWgZdNl01lgQERGFgqECC64VQkREFFrGCizcGQvWWBAREYWCoQKLs8NNmbEgIiIKBYNmLFhjQUREFAqGCiwcnMeCiIgopAwVWNg5jwUREVFIGXO4qcMGOOyh3h0iIqKIY8zhpoLdIUREREFnqMDCYfaYoZwFnEREREFnqMBCM1mg6cEFAwsiIqKgM1RgoUTFOG8ZWBAREQWdAQOLOOctayyIiIiCzrgZCw45JSIiCjrjBhbMWBAREQWdAQOLWOctayyIiIiCznCBheYOLJixICIiCjbDBBbzdxzH2gwT7O71QlhjQUREFGyGCSzGTtmMCTstyNe4dDoREVGoGCawsFqcT8Vu5jwWREREoWKYwCLaFVgUuQMLZiyIiIiCzTiBRZRJ3RbpC5FxHgsiIqKgM1BgoWcs9OJNZiyIiIiCzXBdITY9Y8EaCyIioqAzXMbibGDBjAUREVGwGS5jUegOLFhjQUREFGyGy1gUghkLIiKiUDFwxoI1FkRERMFmuIxFAVwzb9oYWBAREQWb4WbeLHBP6c3AgoiIKNgMN0GWO2PBGgsiIqKgM05g4cpY5LmLN5mxICIiCjbj1ViwK4SIiChkjJexYGBBREQUMobLWORpUc4fsMaCiIgo6IwXWDhYY0FERBQqhusKyXW4Mhacx4KIiCi8A4tx48bBZDIV29q3b49wyli4AwtmLIiIiILOdRauuE6dOuH3338/+wBRlX6IgGYscuyu/XHYAIcdMFtCu2NEREQRpNJRgQQSKSkpCDdWi3OCrByHa1SIXsAZHR+6nSIiIoowlQ4sdu7ciUaNGiE2NhZ9+/bFyy+/jKZNm5Z6/4KCArXpsrKy1K3NZlObv1hMmrrNLjrbu2PLOwOYPAKNCKO3rz/bubpjm/him/him/him/iKtDaxVfB5mjRNc56RK2DmzJnIzs5Gu3btkJ6ejvHjx+PQoUPYtGkTEhMTS63LkPt5mzhxIuLj/ZdN2HzKhP9us6BJgoaF9ltghh2/dXoT+dF1/PY/iIiIIlVubi5uuukmZGZmIikpyT+BhbfTp0+jWbNmeP3113HnnXdWOGORmpqKjIyMMnesshZuP4o7v16PNvUTMCv/JpgKc2B7YBVQuwUilUSXs2fPxpAhQ2C1Rm7mxhPbxBfbxBfbxBfbxFektUlWVhbq1q1bbmBxTpWXtWrVQtu2bbFr165S7xMTE6M2b/Ii+POFiI91zl9hs2swRcUBhTmwwi7/CJHO321tBGwTX2wTX2wTX2yTyG0TawWf4znNYyHdIrt370bDhg0RLqNCCoscQFSs84e2vNDuFBERUYSpVGDxj3/8AwsWLMC+ffuwdOlSXHXVVbBYLLjxxhsRLvNYFNolsHBlSDitNxERUVBVqivk4MGDKog4ceIE6tWrhwsvvBDLly9XX4dVxsIa5/whJ8kiIiIK38Bi0qRJCFclZywYWBAREQWTcdYKiSqhxoKBBRERUVAZJ7BwdYU4NMBhYY0FERFRKBgmsNCn9BYOdoUQERGFhOG6QoTD7AosuHQ6ERFRUBkmsIgym2CCcxJRu7srhIEFERFRMBkmsDCZTIhy9YbYTc5ZOFljQUREFFyGCSyE3hvCjAUREVFoGCqwcA0MQZFeY8HAgoiIKKgMFVjoXSE2d1cIAwsiIqJgMlZgoWcsWGNBREQUEobMWBQyY0FERBQSxgoszF6BBeexICIiCipj1liAGQsiIqJQMFZg4Xo2BbA6v2CNBRERUVAZK7AwOWfeLGTGgoiIKCQMnrFgYEFERBRMhqyxKOCoECIiopAw5Myb+RprLIiIiELBkBmLPD2wsOWFdH+IiIgijbECC9ezyXMwY0FERBQKhgws8rUo5xessSAiIgoqQ3aF5Gqu4k2HDXDYQ7pPREREkcSYgYXdlbEQzFoQEREFjbECC7Nzgqw8h+XsD1lnQUREFDQGCyyct/kOM2BmnQUREVGwGXPZdLsDiIpzfsPAgoiIKGiMuWx6kQQWMc5vuHQ6ERFR0BgzY6ECi1jnN8xYEBERBY3xMxYs3iQiIgoaQwUWFs8aCytrLIiIiIItAjIWDCyIiIiCxcCBBWssiIiIgs1YgYVJ8xhuqgcWrLEgIiIKFoMFFs5bZiyIiIhCw1iBhevZFHAeCyIiopAwZGBhK9YVwsCCiIgoWIzbFWJljQUREVGwGXNUSLGMRV5I94mIiCiSGDJjYXdocFg48yYREVG1CixeeeUVmEwmPPLIIwinjIWwm6OdX7DGgoiIKPwDi1WrVuGjjz5C165dEW4ZC1FkZsaCiIioWgQW2dnZGDVqFD7++GPUrl0b4cJsAkyu4KJIz1jYWGNBREQULFFV+aPRo0fjsssuw+DBg/HCCy+Ued+CggK16bKystStzWZTm7/IY0lQYTWbVfFmgRaFRAAOWx7sfvw/1Ynevv5s5+qObeKLbeKLbeKLbeIr0trEVsHnWenAYtKkSfjjjz9UV0hFvPzyyxg/frzPz2fNmoX4+Hj4mxl2ACZs2r4HAwEcTz+I5TNmIJLNnj071LsQdtgmvtgmvtgmvtgmkdsmubm5/g8sDhw4gIcfflg1YmysazhnOcaOHYsxY8YUy1ikpqZi6NChSEpKgj8jKdmv+Jho5Ofa0LJDVyAdqFc7ESNGjEAk0ttkyJAhsFqtod6dsMA28cU28cU28cU28RVpbZLl6nHwa2CxZs0aHDt2DD179nT/zG63Y+HChXj33XdVl4fFYin2NzExMWrzJi9CIF6IaNfQEIclTt2a7QUwR8ALXpZAtXV1xjbxxTbxxTbxxTaJ3DaxVvA5ViqwGDRoEDZu3FjsZ7fffjvat2+Pxx9/3CeoCAU9sCg0uRqAo0KIiIiCplKBRWJiIjp37lzsZwkJCUhOTvb5eahEW5yBRQE4jwUREVGwGWrmzWIZC3dgwYwFERFRWA839TR//nyEY2BRAFdXCOexICIiChrjZSxcXSH5emDBjAUREVHQGC+wcGUs8jXWWBAREQWbcTMWmitj4bABDpk0i4iIiALNcIGF1eJcLCRf8ygfYdaCiIgoKAzbFZKnZywE6yyIiIiCwrCBRYHDBJj1Ak5mLIiIiILBsDUWhUUOIMq1ngmHnBIREQWFcSfIUoGFa40SdoUQEREFRWRkLNgVQkREFBTGzVjYHYBVDyyYsSAiIgqGCMlYsMaCiIgoGIwXWLDGgoiIKGQMG1gUSFcIayyIiIiCyrAzbxbvCmHGgoiIKBgMF1hwHgsiIqLQMWxXiE11hbDGgoiIKJiMF1hwHgsiIqKQMV5gwXksiIiIQsa4gQXnsSAiIgo6g3eFsMaCiIgomIw7j4UKLOKcP2SNBRERUVAYN2PBUSFERERBFxk1FpzHgoiIKCgMPvMmMxZERETBZPDhpqyxICIiCibD1ljYHRrsFj1jwcCCiIgoGAybsRB2U7TzCwYWREREQWHYjIWwuQML1lgQEREFg2GLN0UhMxZERERBZbjAwmQynV3h1OwKLGwMLIiIiILBcIGFiNEnyQIzFkRERMFkyMDCPeQUVucPWGNBREQUFIYOLArA4aZERETBZMjAwurqCilAlPMHDhvgsId2p4iIiCKAoTMW+ZqrK0Qwa0FERBRwxgwsLCUFFqyzICIiCjRjBhb6cFPNDJj1Ak5mLIiIiALN0IEFl04nIiIKLkMGFjHuFU7tXDqdiIgoXAOLDz74AF27dkVSUpLa+vbti5kzZyJcayxUxoJLpxMREYVnYNGkSRO88sorWLNmDVavXo1LLrkEV155JTZv3ozw7QphxoKIiChYXBM9VMwVV1xR7PsXX3xRZTGWL1+OTp06IewmyPKssShijQUREVFYBRae7HY7fvjhB+Tk5KgukdIUFBSoTZeVlaVubTab2vxFfyy5dcUVyC8sgsMSrdIyRfk50Pz4/6oDzzYhJ7aJL7aJL7aJL7aJr0hrE1sFn6dJ0zStMg+8ceNGFUjk5+ejRo0amDhxIkaMGFHq/ceNG4fx48f7/Fz+Lj4+HoHw/R4zlhw1Y1gTO17IfxF1s7dhVfMHcbh2n4D8PyIiIqPLzc3FTTfdhMzMTFVn6bfAorCwEGlpaeqBJ0+ejE8++QQLFixAx44dK5yxSE1NRUZGRpk7VpVIavbs2RgyZAhembUbXy5Pw30DWuCfGU/BvGcuiq54D1rXGxBJPNvEavWYLCyCsU18sU18sU18sU18RVqbZGVloW7duuUGFpXuComOjkbr1q3V17169cKqVavw1ltv4aOPPirx/jExMWrzJi9CIF4Iecy4aOfTkhILs2tUSJRmk18iEgWqrasztokvtokvtokvtknktom1gs/xnOexcDgcxTISYTXzpp2jQoiIiIKpUhmLsWPHYvjw4WjatCnOnDmj6iTmz5+P3377DWE5j4UEFpzHgoiIKDwDi2PHjuGWW25Beno6atasqSbLkqBC+pfCSbHhpvF6xoKBBRERUVgFFp9++imq7VohDCyIiIgCzpBrhXDmTSIiotAwZmDhWWMRxRoLIiKiYImcjIWNgQUREVGgGXvZdNZYEBERBZUhAwtrseGmemDBGgsiIqJAM2RgwVEhREREoREBxZucx4KIiChYjBlYMGNBREQUEhEUWLDGgoiIKNCMPSpEdYUwY0FERBQshgwsoi0Wdct5LIiIiILLmIEFayyIiIhCwtCBRZFDg8PCGgsiIqJgMXRgIQpNVucXRXmh2yEiIqIIYcjAwmoxub8uNEU7v3AUAfai0O0UERFRBDD0BFmiAK6MhbCzO4SIiCiQDBlYmEwmd3BhgytjIVhnQUREFFCGDCyKjQxxmACzK2thY50FERFRIBk/sOAkWUREREFj3MBCX4jMc5IsdoUQEREFlOEzFgUSWFjjnD9kxoKIiCigDB9YFM9YMLAgIiIKJON3hbDGgoiIKGiMG1hw6XQiIqKgi5DiTWYsiIiIgiEChpvauXQ6ERFRkBg+sLAVacxYEBERBYnhu0IKpHjTyhoLIiKiYIiw4k1mLIiIiAIpQgILzmNBREQUDBESWDBjQUREFAwRMEGWjAphjQUREVEwGDawiCkpY8Fl04mIiAIqwmosmLEgIiIKJMMGFlauFUJERBR0EbJsOmssiIiIgiHC1gphjQUREVEgGX9Kb9UVwhoLIiKiYDB8YMF5LIiIiMI0sHj55Zdx3nnnITExEfXr18fIkSOxfft2hPVw02LFm8xYEBERhU1gsWDBAowePRrLly/H7NmzYbPZMHToUOTk5KBa1FhwHgsiIqKAiqrMnX/99ddi30+YMEFlLtasWYMBAwYgfLtC4p0/ZMaCiIgofAILb5mZmeq2Tp06pd6noKBAbbqsrCx1K9kO2fxFfyz91gzN+f9tdthMVlgBaEX5KPLj/wx33m1CbJOSsE18sU18sU18RVqb2Cr4PE2apjnPwJXkcDjw5z//GadPn8bixYtLvd+4ceMwfvx4n59PnDgR8fGuTEIA7MoC3tkchfqxGl7seBhDtjwGmzkWM7r9N2D/k4iIyKhyc3Nx0003qaRCUlKS/wOL+++/HzNnzlRBRZMmTSqVsUhNTUVGRkaZO1aVSErqPoYMGQKr1Yp1B07juv+uRJNasZh3dxtY3+kCzRyForFHECm824TYJiVhm/him/him/iKtDbJyspC3bp1yw0sqtQV8uCDD2LatGlYuHBhmUGFiImJUZs3eREC8ULojxsXE62+L7RrsMbVUF+bHEWwmk2A5Zx6gKqdQLV1dcY28cU28cU28cU2idw2sVbwOVZqVIgkNySomDJlCubOnYsWLVogXJU43FTYWcBJREQUKJW6dJehplIb8fPPP6u5LI4ccXYr1KxZE3FxcQjLmTc9VzfVR4ZEJ4Rux4iIiAysUhmLDz74QPWtDBw4EA0bNnRv3333HcJNtGfGwmwBzK4UDueyICIiCo+MRRXrPEM6QZbNrsHh0GCW7pBCG6f1JiIiCiDDrxXizlpw6XQiIqKAi5zAgkunExERBZxxAwtXV8jZab25dDoREVGgGTawMJlMJS9ExhoLIiKigDFsYOG7EBlrLIiIiALN0IGF1WLyrbHgcFMiIqKAiaCMBWssiIiIAi0yAotio0JYY0FERBQoxg4sPIs3OY8FEZUk8xBgLwr1XhAZhrEDiyhLCcWbrLEgIpe0FcAbHYHpY0K9J0SGYfDAgjUWRFSG/UuK3xLROTN0YBFj8ayxcK2+yhoLItJl7HTentwLFBWGem+IDMHQgQUzFkRUphOuwEKzA6f2hnpviAwhggILzmNBRB5ktWY9YyE8vyaiKjN2YOHqCilQXSHMWBCRh9wTQP7ps99n7Ajl3hAZhqEDC6tnxsLKGgsiQumBBDMWRH5h6MCi+CJkzFgQUQmBhMk5LJ0ZCyL/MHZg4cpY2IrNvMkaCyLyKNxs3v9soCF1F0R0TgwdWMRwVAgRlZexaDtM0hZAQSaQfSzUe0VU7UXQWiGssSCiEgKLBp2B2s1cP2N3CNG5irwaCxsDC6KIJ5Nhndrn/LpuG6BuW+fXDCyIzllEZCwKiq0VwsCCKOJJUCGTYkXXABIbng0sTuwK9Z4RVXsREViwxoKIitEzE8mtAZPJmbXw/DkRVZmxAwvPtUI4jwUReY8I0QMKdoUQ+U2EZCzsHhkLBhZEES/D1eWR7BVYnD4AFOaGbr+IDCCCijdZY0FEpWQs4pOBuNqygAhwcndId42ououg4aauwMJRBNiLQrtjRBRaepeHHlhInYWevWB3CNE5iYjAwlaknQ0shJ0FnEQRK+cEkHfK+XWdVmd/7q6z4JohROci8lY3FZzLgihy6d0gNVOB6PizP+fIECK/iJzhpmYLYLY6f8E6C6LI5d0NouPIECK/iJDAwu78AYecEpHe1aHXVOjck2TtBjRH8PeLyCAiI7CQrhDBSbKqFYdDw7EzDALJz/TZNb0zFrJeiGQ1bblA1uGQ7BqREUTOcFPBpdOrla+W70efF+dg2gYe5CkQGYvWxX9usQJ1WqovTXodBhFVWuQsmy6YsahW5m13LmE9ZyuXsiY/sduAU3uLd314cmUxGFgQVV3kFG8KLp0esi6NX9YfxrGsyrX7zqPZ6nZrelaA9owicvExmcvGmgAkNfL9PYecEp0zQwcWVs+1QgQzFiHxvw2H8dC3azH+f1sq/DfZBUU4dNrZZbX7ePbZ4JDIL90grZyTYpUSWDBjQVR1kTFBll1TV83uGgsbayyCac1+52REa9NckxJVwK5jzmyF/vrtyTj7PdG5T+VdQjeI+jm7QojOVUQEFmen9WbGIhS2HHZ2ZRzOzEdmnq1Cf7Pj6Jli37M7hAI6h4XOVdBpyj6KKDsXIyOqCmMHFq6uEGHj0ukhIZkiz6Bg+5HiAUNpdnoFFtvSK/Z3RBVb1dRrRIgurhZQo4H6skZ+ehB3jCiCA4uFCxfiiiuuQKNGjWAymTB16lRUh8DCucIpl04PtrSTucgptJ8NEI5ULPOw09UV0rlxkrrdWsGAhKhSq5qWxNVNUqPgSJB2iijCA4ucnBx069YN7733HsKd2WyC1WLyXeGUgUXQbPHqwthW4YyFM7C4oquzcn8bu0LoXOWeBHJPlJ2x8Ag6EvM5fwpRVURV9g+GDx+utooqKChQmy4ry3mCsNlsavMX/bG8H1OyFja7HTn5hbCbrbCoxU1z4fDj/w5XpbVJMG086CzYrBVnxek8G7Yezix3fzxHhAzrWA+v/LoNx84U4MjpHCQnRFf7Ngk3kdImpqNb1QFPS2qMIlO0POES72eu3UodJ6QrxOhtUhmR8j6pjEhrE1sFn2elA4vKevnllzF+/Hifn8+aNQvx8R4rC/rJ7Nmzi//AIYcIE+bMnY9BJ9Mh1ym7d2zB1uwZiBQ+bRJEC7ZKUsyMzkkFWJxnxpZDpzFt+gyYSxjpp9uvkhpRSLJqWLd0HpJjLMjIN+HLX+agXU2t2rdJuDJ6mzQ9sRA9ABzXamHZjNI///WyTqGf6gpJN3ybVAXbJHLbJDc3NzwCi7Fjx2LMmDHFMhapqakYOnQokpKc/ef+iqTkxR0yZAisVtcqpgBe2rQAOWcKcH6/C9Fi+x/A8d/QqmljtBg6AkZXWpsE00ubF0jeCvdd1gcrvliDAjvQrd9ApNYuPaic/MchYNNmdEpNxogRvTE9cx1mbTmGWs06YkS/ZtW+TcJNpLSJee5qIA1IbnsBRgwr4/Of2QV49zVVYzFk0MWwxriKviNcpLxPKiPS2iTL1eMQ8sAiJiZGbd7kRQjEC+H9uNFWZxmJw2SGJdp5MrM4CmGJgDdBoNu6PCeyC3A0y9kN1r1ZMtrUT1Q1F7uO56Fl/Zql/t2eDGdU3C4lSe13x0Y1VWCx41iO355HqNoknBm+TU7uVjeW+u3L/vzXaQ4tKg7mojxYcw7DWqN98PaxGjD8+6QKIqVNrBV8joYebuqzEJlVL97kPBbBsNU1RLR5cjxqxEShfcPEChVw6iNC2jSooW7bpyRVakQJUdkjQsoo3BRm89n5LDi1N1GlGT6wcE/rrYabclRIMG1Jz1S3HRs5A4P2KYkVChD0ESGS4RAdXAHJjqPZKNKnZyeqDHsRcNK1+FhyGUNNXTSZ8pszcBJVSaW7QrKzs7Frl2uSGQB79+7FunXrUKdOHTRt2hRhvcIp57EIyYybHRsmeWUezlRoREhbV8ZC6jESoi1qPoy9GTlo08AZaBBV2On9gMPmXIgwqXG5d9dcwYfpxNljHREFKGOxevVq9OjRQ21CCjPl62eeeQbhvV4IMxahmsPCnbFwZR72ZeQgz2PSrJLWCKmXGINa8dHu+UjaubIdnCiLzm0q79bOro4KBhZgYEEU+MBi4MCB0DTNZ5swYQLCeun0YoEFaywCLd9mx+7jOerrjg2dhZr1asSgTkI0ZD24ncfOlLlGSJv6zmyFrr0r68GJsujcVjUtvxukeMaCXSFElRUxxZsFrLEIKgkQ7A5NBRINkpxdUDIF/Nk6izNlrhHS1qu7o4OesWBgQYGaytuTXmORdxLIcc3WSUQVYvzAoqQaCxsDi2DWV0hAoXPXWZSyqJj3iBBdBz1jwa4QCkLGAtZ45EbXLd6NQkQVEgGBhcy8yVEhoa6v0JU3MkQfEeKdsWjr+rv0zHyczi0MyD5TBAQWFc1YADgT09D1twwsiCrD+IGFPtxULZvOGotQjQjRec5lIbU5pY0I8a6xSIq1oklt5wyIzFpQpeSdAnIzyl98zEt2LAMLoqqIsK4QZiyCweHQ3LUQ3hkLmZtC1gk5mVOI49kF5Y4I8XS2G4V1FlQJGa6RHYmNgJjiAWtZsmMbFc92EFGFGD6w4DwWwZd2MlfNOSFBXcu6CcV+FxdtQfPkhBLrLPQRIfr8Fd70ibL0GT2JKj3UtBLYFUJUNYYPLKwWUwnDTRlYBKO+QuopolxdUSV1h2z36tLQR4ToM256O1vAyYwFVWVESNtK/Zm7K0Qm12L3KVGFRWZXiKPIOcUvBbW+wrtLY6tXgFDaiJCzf+cKSFxDWYkCMiLEpSCqJrSYREBzACf3BGbfiAzI+IGFxeKbsRDMWgR9RIjPyBCvLo3SRoTomiUnINZqRr7Ngf0nnJNvUfWSkV2Aaz5YivfmBWdGy02HMnF036YqdYXAZDo7Aye7QygMrD9wGseywv/cZfzAoqQaC8HUZsgzFlKsqaZaL2dEiM4iU3u7gg7WWVRPXy7bjzX7T+HtOTtxJt8W8P/39E/rUDvvQJUyFsX+hoFFtSDHkddn70DaiVwYzZr9pzDy/SW49fNVPiPqwk1kBRZmC2C2RkzG4lRuITKC/DRPZBfgiCui1qfh9ibDRmVRMckiybohFRkRomOdRfUlQeSklWnumXB/23w0oP9v17EzOHl4F6JNduQjGkWJ5S8+5u1sxoIjQ6qDjxbsVkHrc9O2wGi+W5UGiSdkxF24X1hFVmAhrHEREVj8vO4QBr2xGC+steB/G9KD9n/1N3zz5HjUiCl58dySFhUrb0SIdzdKuH+wyNecrUdx7ExBsfdoIE1ecwgtTc73/l5HCpbsOVXpx2BXSPUyyxWsLt2dcfaYbwB5hXbM2HjE/f3/NhxGODN8YBHjOUGW0LtDclwT5hhMZp4ND09ai4cnrcOZ/CJoMOGxHzfht81n35SBtCU9s8z6Cl07rzkpyhsR4rMYGTMW1c43K5zZisu7OkdbLNmVgWNnAhPgS3Hv1LUSWDgPwLu1hpjyx8FKP45W1yNjEebp50gn3R9S2C1yC+1Yvf8kjGLWliOqm0e6g8X/1h8O6+6QyMtYJNRz3n41Elj0n1JrLXILi/Dab9vx66bgnJD9YfmeExjx1iL8vO6wegM+dHErnFfPoQ6yf5u4Fgt2HA95fYX3nBT6kNPyRoR4ZywOnspDVhD66Mk/9mbkYNHODKmHxOPD2qN7ai21yu209YHJpskVq3TJdbA6P7+7tUb4dbPz4FwptZsDJgtQmA2cCV7mjypv9tbiXWsLd2QEpXsv3x7wf4PJa5xB8V0XtkB8tEUd/9YdOI1wFXmBxbWfAakXALZcYM5zwPsXADt+K/Y3UnV7w0fL8e68XRjz/TqVhgpn8tz+79dtuPHj5aoAsllyPL6/ty/+dkkr3NjKgeGdGqiMzb1frcaKPSdCOiLEZxZNPbAoZ0SITuovGtaMLXEeDApf37pqKwa2rYfUOvEY2b1RQLtDfvrD+bi9Epzv9+yE5mo00cyNlQwOLNFAnRbOr9kdEtZ+3+IMLLo1qaluFwb4QkoyBvd+vRbPrLa4j1+BcCQzX2X3xKjzm2Fwhwbq6/8FKCj3h8hZNl3vCqnfAbjjV+Dqj4EaKc7x6ROvB765HjixWxXGjHxvCTYeynSn1H73ioTDiQynu/qDJfhg/m6Vqb2hdyqmP/Qn9GpWW/1e5gd77douuKR9fXVgvWPCqoBFuvk2O3YfdxZjdmzo/HCXRh/dIYFQemZeuSNCSizgLGVq7z3Hs9VBJpxThZFE3hc/rHaOzPjrBc3U7eXdGqms2vqDmSqb4U+SldAzjU0cziu9Nh17FAs4KoUFnGFPFiZcuc/Z9fHsnzu5L3KOe9T0+NvsLUexaNcJFDhMeGNO4IZPT113SGX3+jSvg6bJ8biimzMon77xsFo+IRwZPrCwemcshORju14P/G010O8hwBwF7PwNjvfOx6IPH8KpzNNoWS8BV/dwVpFL10KJbHnAkU1A+npZIMN9EH137k73KIdApd+mb0jH9R8uw+XvLMamQ1moFW/Fh3/tif+7tqtP0aRkbd4f1RP9WiWrqbZv+XSFu8vCn6QAU7pd6iREo0GSx9DeEtSMt6KRK/Mgz6UiI0J8Cji9MhYFRXa8MXsHLn1zIe76cjU+Xbz3HJ4N+cvMTek4lWtTr/fAdvXVz+rWiMGFrZ3LkksthD/N2JiOPJsdXZI1WPOcV3r9z79A3S7fe8IdxFaYZ50FhaX524+rY49csPRsWhudGzsvPhbtDEzWosjuwL9/2+7+fvbWY9h40Hkx6k9ycfSjqxvk6p7O89GAtnWRGBuFo1kFWOUKpsJN5KxuWlRCd4bMqjf0eeD+ZTic3Bdmhw33mKZgcfw/MW3gMdx/UUuY4cDuHZuQvflXYPmHwPR/AF+OBN7oDLyYAnzYH/hoAPBWV2DW0/hx2nS8Nms77v96jd9nh5ShnDKx0J/+bx5GT/xDRehRZhOu7N4Ivz0yAMM6u6YgLkGs1YKPb+mNnk1rISu/CDd/usLvwY9nfYVJgrdy6IWYv6w/XKERId5/55mx+CPtFC5/ezHemrMTNruz3eV10IezUuh8s9zZDXJjn6bu4jMxssfZ7hB/Zpd+chVp3trWVYOT2BCNUxrggpZ1VFav0oGMPhU4u0LClmQPxJCOzm6CAW3qBbQ7RDJfUhdWMy4KXWo7Lyr/M/tsoOEvkjmX/yNrXo1wFT3HRFkwrFNKWI8OMX5g4cpY6Ccbb3Lyf255EfodehD3FD6Kk9YUJDsyEP+/u9FmYl9si70d86wPo8YPNwC/Pg6s+hjYMw/IdE26E1sTiK7h/H7p2xi1/mbMjf47rjj5GeYtWuC3Pra/f78efV+Zq6JkKUqrWyMaD13SGkueuARv/aUHGiR5zCpaioSYKHx+ex8VzZ/IKcRfP1lR+as3P9RX6PQhpxtckX55I0J0HfSZO4+cUWnv5/63Rc3mKB9AaZd3buyB/q2TVdfPPydvqFC6UN4HUqfy1JSNhhqmFmoyemf1/lMqAL7hvNRivxvaMUXNpLrvRK7qEvGHAydzsXzPSZWUvKReVrGl0q/u0cQdeFQqkHEHFsxYhCPJVOqF6YP1wKKtK7DYmeH37gLJSr/xuzPIlIvPkc0dKmCWrMlqP2cQfnJ13Q3tlIKkWNccTIC7O2TmxiMqexJuImt10xLeIPd9vQafLZGUuQndhvwVtR9bCwwc65z+O+sgomFDgRaFA1FNgfaXA/0fAa58D7jjN+CxPcDj+4HHdgM3fI3DjYchT4tGS/MRPBQ1FYPnXQntvQuAhf9W9RtVIQfA+79Zgx//OKiegxQmvXFDNxVQjBnarkIBhaeacVZ8ecf5qpZBApRbP1up+ieDOSLEu0tDV96IEF2LugkqYJT6l0tem69ePzlPSKpw9qMXqQ/dK1d3VdXTktX5ctm+ctt4/P82qzoVGRL54YKqvVZUerZiaKcGqO/1XpVAd0jHFL8WcU5xZSP6tkxGnbz9xboyhndJUccDqQPSa6gq1RWSdRAoyGbtTpiRQFIuMOonxqBrY2dtl3SHyCR8J3MKsdnP3b5fLN2H9Mx81bX31z6pqBsLXNvTeaL/zyz/ZbXkeK9/Lq5xdYPopFtbupzlAnFZgAvyqyJyRoV4RXUyVPGWT1eqFJrcR65yR1/cGqboeGDgE8BD64Cbp+LI7SvQoWACBuS8gsPDPgGGjAd6/BVoegGQkOys17DGAh2uwCOOR9Cr4ENMaTEeC0y9UahZYDq+FZj7AvBOT+DdPsBXVwE/3QP89hSw+A1g7dfOUSmH1gCn05x1Gx7m7ziOtWmn1ZXdj/f3xc8PXoirejRR6bCqkjfkF3f0QUpSrOoOueuL1SrIOhdyVSCFr5XJWOhFmLryRoToZMVUvdtEJlxqXCtOPZ/Xr++O2gnOGg0ZeTB2eHv19f/9ur3MtUU+WrhHTTWte2fuTo448YOcgiL3iV6q2Uuijw6RCvdzvfKSE77eDXJNzyZnuy5cxZeJsVZc6kohV6qIM74OEO+sB7Ed24nrP1qGi1+bH5Qpyanio0EGdWigJt8Tckzv17I2hppXIfGnG4FJo5zHWYf9nOcJen++88Lj0SFtEWN1HocfuKil6naXk/xS1wiOczVv+zFVmyQBk16P5HkMHN7Z1R3i6koOJyVPjWjIGouzBy2pFJYrdUndJ8ZE4dPbzkOfFnWK/2FSQ7XJS9e7xSms3HsS0zYcxj0DWpWa8pX7WMxx6DvyPszYeCX+Nm0lrq+xHmObboFl70IgY7tzK49kSyzR0CxWdM0HFkWbER8fh+RpCYDF6hwCpzarc8Iv2SwxPl+bTVFoc2QfzMv3yHSXrgl+NLVaYyNNw/+6FWDSqv0oPGjHb+9PwhXdU2GOTQJikgCf25rOW0vJb5k9GdmqMFQ+0C2T4wC7zbkqpMwBIFOpl1BzIZkHWdZe76aqyIgQ3ZAOKSpDckvf5njs0nbq6tebnMymb0xXVzSP/7gBE+9yFvB5kiuCV2ZuU1//67IO6r4yCuifk9fjx/v7lbjsO1WMFD3LlWTLugnqCqskkrKuHW9Vi5Mt3X3CncKuCqmzkW4VyVQNk4Pu8l0+y6Vf1bOxqumR7ckRHdwXHuWSx0jLwOxFi7Bqn/MYIEGTvP8odCSY1EftDenoLAxGYQ6w9hv85+jbSIo+AEjvhGzbpgE1mwK9bgV63AwkOrtNKkOymRJcyIXN1T2bwOFaJbtRrTjcdH5TTFi6T9V2/dgquUJ1ZmXRizZH9mhc4nFIMrOSYZURUM+P7HxOF5v+ZvzAwqsr5OCpXNz86Uo1xE364yeomoOyh0ZKcaQEDXKgLC2w+Mp1xTu0YwOk1IxVb7KPF+3BJ5n90ajl3bjjmkTg8Fog57jHluFxK9sxwF7onG68KB/ytpTDcbI8BZmgsJKTFMrbrKN8kT65xN/LIfxv8oV03clsx/Mq8KDWeOcmQYNmV6NhHI4ipBYVYVeMHVEmB/BCSX9ocgUYeqBhgdVsxupoDYUOEzSTBbU+jHcGQDJKR7+f+tp89msJmixWPBwVgwe7WWGxxQIzJZCSQEu/jVZ/Y4YJH6ba8eXB/SjYD6z/djq6NqmF1ke3w7xsN/adLsC2VWm416KhT/NaGIRtuKGRDZ/v3YvCdDvWfvU/nNe8tvO5qtelELAXOCdVU9973crVkFzdJqY4hzLLgauGa5OfyeRs8jwi5ID/zQrnZ0I+C6UdZK0WMy7r2hBfL09Tw+rOJbCQKbyFBBUJVtPZpc49VjX9U+u6akSKBDLSL68X+1WoOyRtKXZvXQvAeQz4evl+3HxBs3M+gVDVSTeHdEvEWS3oV68Q+H0csPpzIP80JB96WkvAd45BuP2Cxoje+C2QmQbMfR6Y/7Kza7v3HUCLASVe+JRU6/aZa6TZY5e2V3UVngmQBwa2wqRVafgj7bSqt7i4vSvQqQLpwpGMhTv7VoLzmtdRo+9kdMiiHRnu+pJwEDmBhd2hpo2+5bOV6o0o6fOv7zpfXTWXZ0Tnhnj2583qTSwLG7X2KjKUbhU95Xtz32buURgPDWqDsT9txPvzd+EvfS5GfJshZf8jySgUnAHyTkGz2zD6q+XYfywT1/dsgFv7NHaevCQToE5ituInOnVy8/y6EPbCXBzctxupjSRFKCc0k+sDJLdwf592Mg+Ld5+AWXOgV0oU2tR0APlZQEHW2VuZUEzIrf61i7SwGlxa5mdTAxwS3RcBHh/Gmp5/l1W5wqeKnKJrAXhIdlA2qb3bCahR7ocBudZ8XB5ENnn5DgHyyj6kB1tSmlF2eUblSIAkKfUa9V0BhufrYfb42uNW2sy92Uv53u7KVsU618Jx35bwM1mEzx2kyddRMGsmtD66E2YJBKwxzn3xfE9KYKUyXXrGS/+Za+0dGV0VneDanF9vPWHH4cMHkRCVgGtk2LZc2envHbmiVLfO72+rcxRZ5g1I2FSEwubrEG11BZZ6QCnt4A5IpZ0szu5HFeTGqdt8UwwWbNgJKyy4Vv6fdCvK50GCzZpni0blyk+6Xz5ZvBdT1h6scGBhT26j3iZ/Nc/CoJq7sSevBo6cSMKBaUvQNLVF8SAyro4zQPYiXSfx0VHFRsaEFU3Dit3H8Pvmw7jnwqaoF29xFqaXkqUMB7O2HEUn0148XXMeYt+b7zrGSH9vS+CCB3DD/CbYftKBFs17YejQZ4HNU4HVnwEHVwJbpjo3Ke6VAKPbjc4Lg1K8NWeHWjyvd7PaGNzBN2iQGqJb+zZXXauStRjYrl75Qad8FrKPOj9TcvEhnyFX94ZkcqXQXi9y9ybvo8u6NFI1ZjI6hIFFEHmmOq/7aBlO59rQun4NfHVnHzSs6VqQrBzSb39R23qYs+2Yylr8fWi7Yr//ac1BVUgoqXwpGtNd26uJSp3tP5GLz5fsUzUcZZI3oXQ9xCZh9uYjmHFUCpDq4ooRlwCu2oHKcNhsWDdjBhqNGAGz9WxFsbem8v5eshfj/rcFOAi8ekFXXN+7eAW/Cmgk6MnPVCcDzWTGpNWH8dGifSiCGd2aJuOFq6XGIdZ1EpATgNl50pOTkLq1nz0Zun42Z8thvPbrFtzeLxXXSwGUzAdS7H7OrIjztqiUbEGBR5Alt1KM6jr5aRo0zYG5W48i40w+GiRGo3F0LnaciUKBrQjJCbG4sG09WNSJwHkyl/VV5u/IwOHMAtRNjMGQTo1g1jMhqqtJv/XKlJjMcGQfx959u7F7zx5E5R5DfdNptdU1ZanATWWlZAsjcsJ0Blvf+e0xJVO2Vq/V/I90w5VePyGfirf1t/eMqv0/+VdLXV9oEy1n1wRKbuWTJZIUtgQWv285hsxcm5pTpTxTTzXHSM2E2qZs1C5Yj456sLpmJrDG687y/pfPsQRZMTVU4JVnisPytHwUWOLRt0MzJNdOdv5O7ivvVeEZuBW7hevz4goo3Z8Pu+/P3BlPr4sOz8+J/L6kQFWz43xAbVjrfjJAggTDDWBJqIcepwthnrva2VUsAbKejZP29g5Ci33v/CxWmDwfdSFVdPZCSl1U6RdWReqkPGjFpxgTsxHQR8436w/0HQ20HaZe9/PTN2H7sv1YuPO4GlmB7jc6tyMbnZmNDd8BJ3YBvz0J/D4eSO0DxNUG4moBsbLVVF8fKYxD+ur96G5KwLP9+sMkowDlOdkKkZB/xDliyGLGAx0LsXL5QRSkF2HZ4nz0axztDBzOHPG6TQfOHAUKvWq5pLs5MQU9MmPxhjURrWq0BpZtOJsFlXaWY7Bru9N0BMlRW1Bnaz6KfkhCVGGW63dZwF2/O99jIWD8wMKjb0qCChlVIUMupYCxMv7cvZE7sBgzpK07EpWU71fL97uzFZ4RqqR5HxncBo9+t14t5yuzDsqojIoUQr7xu3No2239m1d6X6vitv4tcCSrQAVCkmWR2geZOlYK3hS5ulVFbHVUoafcZ8pa6ZtJwajzm2Lcnzup51tZlwxog+Yde6NZnXj1wQwEeUVa9svB6LcWIv+UA/FRGnKLTCrAnHxfX1i8JuWS+7c9nYcHX1+AnFN2PFu7I27v75rWuYzhqlKD897SXdhxVCq4B6iC2wtaJKu0qAV2jBtUHzd3igVyM1wTqpWUBfD6mSur4M4yqM3rZxLAyUnDJieUvLJvS8h+OIoKcfDAPjRpmKLmbXFf9ZWaSXH9TPZPHleuumQryEZR/hkU5J6B2ZaDOJNrtFGxoMLkvCqTbIMUSru61vafAXaesqNejRh0a5J0NiCVE4z8H8/v5Ws5OaoMiPz/XDgKc5z7Lv9B7qNn1Zr/yee1kuJiGZEkw5WnbTxcamGp50yuTy6Pwr+L3sbLFyXg4iYa0g/uw89L1qKBOROXtTAjWibiyj4C5J5w7mPeKefmIpcwKl8p2bpNqEY0d9et2XURgmVLEC66SRJVs8DRcSRiLnwQaNyz2O9lPgspzPZZNySlC3D5685i/I2TgdWfOoONfYtK/D9SazdBP0xMOftzOToOli+2ns3ATtFTuHMq+CSi9BW385zZ4YIsdAXQVWLO/UuAs3XlPuRIM1o/i2/2+qUEGAwsAhdYSMpIDvxSQPbfW3qXupx3WSRlKkVhaSdz1ZTYPZo6p8yWgjMZviZDm65yzdTp6c/dGuP9ebvVHAufLtqjhohWZCU7GWEh+3n3n1oiWB4f1k6tk/LT2kMqGBLSVSQ1KJ0bJaFL45poUDNWzakhbSDtOu6Kjrj5HArYJBBrVS/wb355HtIv+vy0LSqokErrCbefV+pMn9JVNnZEB/xr6ia8+ut2DGrfQE2n60366qV46pNFe1ThoJCC4Fv6NcMd/VsguUYM3vp9pxr3/vScEyiI7YC7/tQd4cRus2HtjBloWE5mq6yZYGV0lawHsijt7AH8ota1MWFUR5jk5C9XWhJEyG0J6eHCo2dw1xsLEZVpwqoHB7tH91SErJDa9+U5MDuKMOvB3miRZHIGHBIg6dNxe5GhyS/N2IYpfxwqM7CQIP+JHzeqFHibNu0wcFgftf8NuwAzdy9W828cadEe9w901V7JFbWciOWKURYuKziDg0eP4Y3pfyABeWhTC8jKPIUE5OP8xtFo3yABJtX15GqTEroqi9cnOQPKArsJaacLcSzHhqZ1k5CanOi8T7FsWmmF3a7sm0dwujrtDO75Zh3sJjNev6EX3py7B9uP5aJxrA3vj2yMDjVyUZSZjh2rF6Bdkzqw5B53Xnmr7ZgzI6IHnPrzMZlR6NCQU+hQSRerxYIasdaye0wV7WwArYrV9YJ1Caj1r6NwMKsIPx+pg00Nr8MHN/y5xEfq2ypZXSTJcVsmy2vu3fUt3Xi9bwd63eacQVkyD/mngbzTztv80zh98ji27DmAmqYctK1ph1WyAvI6m8zQTCY1minKGu18HSVraTIjI8cGu2ZCjcRaSEhujDPWZBxHbRy0JWFXXgI2Z8XhpLkOatdPRbNGKWpRxvZ1TEi1ZuH7uauwfMNmXNigCNe1szqzG3qWQ/6vZFE8ttVH7FhyyIbGDVJwbf9Orqx3zTK7dQLN8IGFDD+SYYcyLFEyDVL7UBXSNyqFmVPXHVZZCz2w0OdIkPSq++reg5x8/z60Le77+g81xfSt/Zqrk02Z2YrZzmzFHf2bV2iKa3+Rk7xMCZ4UZ1UnCpk8S4pcZfMe0iSZF5kmvL/XMKhwdlu/5li+OwOrdh/Fxzf3QJPavoGCp5v6NFVZCPeokrvPV20k7TF7yxHM2nwUa9JOuTO8MrpBgolb+jUvlpl6eHAbODRNzQr6wnTnpc1dQQwYA0Umo5q4Mg0/rD6oAiwh55U/tamn2m5Qh/owSRZK0srlaNMgUc1/IiO1ZCSPvqZIeeTz8vacnZCRql1S66JFE9/gviRXdm+sRgPJ5F3frUpTn9+SMm4TVx1Qc6HIRcVLV3UplpEcdUEzrJ+8ARNX7se9A1o6hzrKyS+pkXNzeXbRKsyx18BlXRrimb90V++Bfy/dp65Er6zdCP93Tddyj0vyPKVt5m8/hnnbZQj6KbV+hLLbeeEjx7mWVQjSpbD9idmLcBJJ+Ov5TTGoe2v0atsUt09YpYa6X/1jFj66uRf6dr0IOw8moc3QEbBUIACVzKbMM3O44GzV+Y2dU33asaqe+GQFFhdl4MkuzmHlJZHRYrJuknyGpTvEJ7DQyf406u7cvJ7DqA+WYrMtC9f1aoJ/Xyc5krOKbDbMmDEDI0aMgNXVJmYA38/diddm7UCsw4yikxqKSpuk62Q2sO3sOiOS5dS0ZBQ4LsSwS3oCXUqfTVkXdzgTb7y9GDFHzbi04+ASz0PBZvjAwp8HcTkYSWAxbUO6Gpp49EyBeypZvWizJDJ2XopwZE0P6Wp46jI1VqNEMzalY/vRM2ou+DsvDP7JRw6u0q0hm1QmyyJnMpmQfivL9Uoa+cO/9ir9QxqmJMh778ZumD5jZoUm8ZIThRz0Ze0RGZ/+wDd/qMyT91To8tqO7N5YTVld0rBXfcy7HFrkJCgnFjmw3nlh2d0rlSVXTjuOOmcflXVXKnrwlpNWZSYnlJkOZTIxycTp88PI/5MF8GR2TZlDpCpkim85eb44fat6/8vnrSyy6rCsPjzTteBYZdpTJpYb3rmhCmIe/3GjWsn4/ota45pejd3D9k4WyLTwziBflnr3fl5XdG2EF6ZtwYGTeViw8zgudq2D4knWcpAuVP0CQ4pH5bMlk8FJQbhcpEgN1n9v6YX6ibHu7tXj2QVqLhXZZFi1zCCpB286qemS7jwpYJTj0Lxtx9Rx6OFBbSp1QfLJ4j3qPS3vm8eGOk/S8vff3HU+7v1qjVru/s4vVuG1a7qgMuSi63BmvlqN+Inh7fHod+vw7coDqrurIpnbskjB/HLXxFD6JGulkZFGElgs2H68UsOD5XWQjKUU7Ut3tHdtXXldyxOW7ne/ZpLFbJuSqIapygzDMmePBk29vtIlJ7ey1pLMFizktbikhALRksixTNa22nM8Rw29lXmOQi0iAgt/ubBNXfUG08fcr9h7Qh2QZQ2CsiZ3kgO8vClv/3yV6u+748IWJRaOSneNpM31g2RFisoCSZ6rfCg9hwDmFhapoV3VdYid7HdlivKbJZ/tQtFPYDI99QUtk9VVolRiS7dJRTw6uI2qF3h77i71eLIb8l7wB3lPysq1+vTo0jUngZ9sLZITVFeQvJ4y22r6aVlNNh+HT+fhcKasLpsPi2bBlqgduHtAK58ZMj3JlMVP/LTRHVxJsbJk4SQ7UZUaG0+SpZAhoEt2ncDDk9Zh9b5T+NflHUocny9ddrLQnDxf6e585Zou7mmOK+q167qha5Oaali4BAdPTtmoJke776JWuLp7Cr7bbVZzs8iQYxlW6i0u2oJre6Wqqvxvlu/3CSzkxPR/rjlSpBjaM5sg3S/ymtz/9R+qW/HKd5eojKhcVMhJRiZG8iZZk36t6uLi9vVUMbmecZORatKtM3fbMVUkLvMfyIg0OYmWN0+HZJ0k2BUyr4fnMUeytJ/eep4K3uRi6pEfNuC6FiaMqEDbSlHse/POTiQlQaLMafLUlE3q/S9F0ecyB4jULUkWoFU953u7LFJnId2ZcnEg2ZmKzl0ic0RMXnNQHS9kAkWZRqCiasRE4ecH+2Pv8Ry0qp+gJiMs6Zgp2T3P4/++EzlqCXYZCVLReSnkcSXIlYzotPXpDCyqGzXmvktDVaz5w5qD7hnWKvIBGdi2nhqmJKnXS15boE5KcoUmbyz9gCxpd7kiToqN8tsJx9/kYBNppAtFDsCSwZETqKzQWZEi3JIOAHKQlWBUrpCfm7ZFXaXIPA9Sv1LVYE36jm/9fKW68pWDpmQu5IQoV1oVn87YhI8X78MXy9JUrdA9F7UsVvsiV4hykpSDrX5F9ewVnXB514Z+CzLlvSXTzb/5+w68M3eX+pxtOHga743qWazbSq7g5QpaAiLpfpK6KRnTX1kSGNx7USv1+ZX6kI8W7laP+ewvm9VwwTP5ZtWer1zT1T2jo7dRFzRVgYWc1KXr0DPIlJ/J512mEZcsgjcJEqaO7q+ei1xtfuEx+6s0afPkBLVap1zpnt+iDno3r13iyUaGv39223lqJU/J9sgVsGTFZJ4NWUK8pEyKTqayl6tkefySasTk+ctaRPJ+l9f++z0WnLfuMK47r+yuqvcX7HJPJKXPwyDBVMaZQlVvJG2cnBCj5jA5l9k2y8tW6Ff08n7NyC7E6v0nVbuXZ83+U6pt9GxVVbp8G9eKq/BFh5CslnzmqlJzdkW3hqqrXTKHEtCG+sIv8s4S50gmy5IDnl5zIBOUVGQsvLzQL17VRa37IQcRffY/uYqUYEUeV79ykIJNzwVnKLRUkeqf1YDMc+bMXkm3iKau6CatOqA26V66rneqmmOhrBocb3K1e+eEVWrNgNQ6cfji9j7qJHzgVK66WpIroD0ZOSr4kKvglKQYNUugc4tFo5pxqFcjCt9OX4A/8pKxJu00vlt9AN+vOaCuoOXEeyyrAM/+sklNxCOu791EXd0Gov7H2WXQDj2b1VapcymOvOztxXjzhu5qwiE5oTw0aa0a3i1Xq3JClazSuZAAQwJ5CfDkguHD+bvdi/M9dHGrMg/08jspCpcM5rcr0vCPS9u5rz7lKlnIiKLSrnblanvKA/3x8cI9qoupXUqSCiaki0P2qzLkImX6Q3Xxw+oDqn9fioklSyon72cv7+iTiZLuk9+3HlMZuBdGdi71ZGRx/T7GYsJnS/fjyamb0aJeInqXEsxJJkwyJ/pJ2XPejocGtcbx7Hw1IZq8vhIY9qvkSVvqHvTJo9yzbZZBgkLJWkhRuowOKS+wkGLgB75Zo+aRGNElBfcMCP96qNb1E7Hm6cFhM/umSQvyijpZWVmoWbMmMjMzkZRUsTUlKsJWQhFNIEh/9J9enec+8Dw6uK0qzqsoaW45WMpU0rI+gne/aa14Kxb982K/FOAEq02qk3Bqk6W7M/DdqgOqi0WfGVYq2GUEyvXnNSmWzSrJ3G1HMfqbtciz2VWdx+e39VFXLOfSJusPncGHC/a4p0n21Dw5Hi9d3aVCV3z+ILPkjv7mD/fKp5d2aqDqCeSIJavXvj+qV5UyR+WR12LKH2lYumYDXrn9UsTFlt2m0zekY/TEP9SMnkufuERd5cuaJWO+X6+yj4v+eUnQuzWl2+Gt33fgsyX7VJAjffz/HN4eo/o0VSda6dIc8vpCdRyTES0SAJSnoKAQ1731GzacNCM5IVplW0qqp/nHD+tVF4Isk/DdPRf4BCyyPw9O/EO976XLQIKWKIsJuQV2tV+SbZP6mZzCItWlciq3ECflNqdQfX0m3zkcWvZh5VODKzTh2NS1h/DId+tU9mLGw75DkD1HOI36eIUq2JUalimj+5c5ijCcjifhdP5mxqKS5EMpc1pI8ZpE+jf28ZpIqhzyIeueWkttT43ooK50ZCrj3zYdUR+oBy9uHRZVvRR4coKW7blcG37ZcFhdaUrNwK+bj6hNTgYD2tXDkA4N1Cx+nhmCSSvT8NTUTeogLTUwMkKnKsOovclV6CfN66h++/8u3KNmlJUT+b0XtcTfLmlT5VFVVSGZl+/v64sXpm1VWcLfNjuDHSmSfe7Kqs2bUhESGFzdozFi09dXaK0YWblVAjpZg0iyAIM71sfrs50LoN03sFVIaqXkvSBF4lLbILUj8r56euomFfC8fHUXTF172N1187dLypm4z+PY99fWDnxxsCY2Hz6janp+fKBfseyqrJkkKzELGaVSUhZEAoE3buiOU7krVVGlnPArSx5DskwVncVU6uOEFAfL61RaAP7SjK0qqJDP3oc39/LLZyoSsdWqQIbS/bLuMC7v1rDMQrfyyEFLL47MG2lXaWvvpcTJ+OTEI8WBssmBWYZvSkZL+oTlalg2OYD2ck0lLH3XemGc9F9L4aK/T7KSWn312m7457D26gpeuk5CQVK7ssCS1BdIJkW6YaTmJdR9yJ6k7f9yXqqqC5G6huNn8tXoKZkr5fZ+oa2VkjlopKvlq2X78O/ftqvho5e/vdj9e+niq0zdVIwF+HBUD1z70QpVD/a3iWvx6a293QGYdP9IICorb+pD8ksiAarUxsjIGCkElsJUtcVEqcJj2SfpCqoVZ0Xt+Gg1r4l0mzhvo1WmqjJTo0s2SR+ZJ0PHpWaiQ0qiKpLUux4lq6F34fzn+m5BmV/HqBhYVIGk/5Y8cYlfH1M+RN7LiFPkaZ+ShKcv76iyWesOnsacrUfV1NMyWkAWwpNNJ9ktqdcI5ElWDsjhQK68yxt+GkqSRXlv3i418mDTYWfXjXSRVrZOIhDkBCzDHy/tnIJxv2x2Z35kZt0KL8LmQUY4fHLLebjuo6VqFI8UikqAIsM/pWBV/p+sOFweyXRI5iJYhnZMUYGF7KNsOsleyAWdDA0WksFR039TlTGwIApDknbu2bS22mS4q4xKkSBD5kSQUREyuqSik0hR4ElG55L2DVRtitQASFGmz3o7ISZD3D+6ubcqgF28K6P8tYvK0KVJTVVQKxP/yVLhUkj74x/OhRile7gqE3UFmtSSSAAhI6UkMyjDevefzFVdI7IJGcb7yOC2od7Vao+BBVE1yZLJVadsFJ7+ekFTd9GrZJICVQNyrmTuFX+shDmsc0P8c1g71f3x9M/OoZnSnSFzaIQjeT0kE+GZjcgpKFJDvmWIrgwnlwnGwnb12WqEgQURkR/IkEapeZF4YkTnqs3PUN3cf1ErVSPxkytbIbMc6zOIVgcyU67UgpRVD0KVV6WQ+r333kPz5s0RGxuL888/HytXrqzKwxARGar7Sor+pOi1tAm1jEbqe2SUidRq9Ghaq1rM+UBhmLH47rvvMGbMGHz44YcqqHjzzTdx6aWXYvv27ahfv2JzmxMRkTHIyJ2Pb+kd6t2g6hxYvP7667j77rtx++23q+8lwJg+fTo+++wzPPHEEz73LygoUJvnBBv6xCKy+Yv+WP58zOqObeKLbeKLbeKLbeKLbeIr0trEVsHnWamZNwsLCxEfH4/Jkydj5MiR7p/feuutOH36NH7++Wefvxk3bhzGjx/v8/OJEyeqxyIiIqLwl5ubi5tuusm/M29mZGTAbrejQYPiFcXy/bZtzlX8vI0dO1Z1nXhmLFJTUzF06FC/T+k9e/ZsDBkyJCKmVq0ItokvtokvtokvtokvtomvSGuTLFePQ8hHhcTExKjNm7wIgXghAvW41RnbxBfbxBfbxBfbxBfbJHLbpKLPsVKjQurWrQuLxYKjR4svUCTfp6RwpjIiIqJIV6nAIjo6Gr169cKcOXPcP3M4HOr7vn37BmL/iIiIqBqpdFeI1EtIsWbv3r3Rp08fNdw0JyfHPUqEiIiIIlelA4sbbrgBx48fxzPPPIMjR46ge/fu+PXXX30KOomIiCjyVKl488EHH1QbERERkafwXCWHiIiIqiUGFkREROQ3DCyIiIjIbxhYEBERkd8wsCAiIiK/CfiU3t70Nc8qOud4ZeZslwVS5HEjYWrVimCb+GKb+GKb+GKb+GKb+Iq0NslynbfLW7s06IHFmTNn1K0sREZERETVi5zHa9as6Z9l0/1BpgA/fPgwEhMTYTKZ/Pa4+qqpBw4c8OuqqdUZ28QX28QX28QX28QX28RXpLWJpmkqqGjUqBHMZnP4ZCxkZ5o0aRKwx5cXNxJe4Mpgm/him/him/him/him0R2m9QsI1OhY/EmERER+Q0DCyIiIvIbwwQWMTExePbZZ9UtObFNfLFNfLFNfLFNfLFNfLFNwqR4k4iIiIzLMBkLIiIiCj0GFkREROQ3DCyIiIjIbxhYEBERkd8YJrB477330Lx5c8TGxuL888/HypUrYQTjxo1TM5R6bu3bt3f/Pj8/H6NHj0ZycjJq1KiBa665BkePHi32GGlpabjssssQHx+P+vXr47HHHkNRUVGx+8yfPx89e/ZU1c2tW7fGhAkTEC4WLlyIK664Qs32Js9/6tSpxX4v9cfPPPMMGjZsiLi4OAwePBg7d+4sdp+TJ09i1KhRahKbWrVq4c4770R2dnax+2zYsAF/+tOf1HtIZtN79dVXffblhx9+UO0v9+nSpQtmzJiBcGyT2267zed9M2zYMMO2ycsvv4zzzjtPzegr7/GRI0di+/btxe4TzM9KOByPKtImAwcO9Hmf3HfffYZtkw8++ABdu3Z1T2jVt29fzJw5M2LfIwGjGcCkSZO06Oho7bPPPtM2b96s3X333VqtWrW0o0ePatXds88+q3Xq1ElLT093b8ePH3f//r777tNSU1O1OXPmaKtXr9YuuOACrV+/fu7fFxUVaZ07d9YGDx6srV27VpsxY4ZWt25dbezYse777NmzR4uPj9fGjBmjbdmyRXvnnXc0i8Wi/frrr1o4kH1+6qmntJ9++klGMGlTpkwp9vtXXnlFq1mzpjZ16lRt/fr12p///GetRYsWWl5envs+w4YN07p166YtX75cW7Rokda6dWvtxhtvdP8+MzNTa9CggTZq1Cht06ZN2rfffqvFxcVpH330kfs+S5YsUe3y6quvqnb617/+pVmtVm3jxo1auLXJrbfeqp6z5/vm5MmTxe5jpDa59NJLtc8//1zt57p167QRI0ZoTZs21bKzs4P+WQmX41FF2uSiiy5S++f5PpHX3aht8ssvv2jTp0/XduzYoW3fvl178skn1ftV2igS3yOBYojAok+fPtro0aPd39vtdq1Ro0bayy+/rBkhsJCDf0lOnz6tPhQ//PCD+2dbt25VJ5ply5ap7+WNbzabtSNHjrjv88EHH2hJSUlaQUGB+v6f//ynCl483XDDDerAFG68T6IOh0NLSUnR/v3vfxdrl5iYGHUiFPLhlr9btWqV+z4zZ87UTCaTdujQIfX9+++/r9WuXdvdJuLxxx/X2rVr5/7++uuv1y677LJi+3P++edr9957rxZKpQUWV155Zal/Y/Q2OXbsmHp+CxYsCPpnJVyPR95togcWDz/8cKl/Y/Q2EfIe/+STT/ge8aNq3xVSWFiINWvWqPS353ok8v2yZctgBJLWl5R3y5YtVepaUnFCnrcs2+v53CUl3bRpU/dzl1tJTzdo0MB9n0svvVQtnrN582b3fTwfQ79PdWi/vXv34siRI8X2X+ayl9SiZxtIqr93797u+8j95X2yYsUK930GDBiA6OjoYm0gqeNTp05Vy3aSdKykatu1a4f7778fJ06ccP/O6G2SmZmpbuvUqRPUz0o4H4+820T3zTffoG7duujcuTPGjh2rlgHXGblN7HY7Jk2ahJycHNUlwveI/wR9ETJ/y8jIUG8QzxdayPfbtm1DdScnSOmfk5NDeno6xo8fr/q8N23apE6octCXE4T3c5ffCbktqW3035V1H/mw5OXlqbqFcKU/h5L23/P5yQnWU1RUlDrAet6nRYsWPo+h/6527dqltpP+GOFE6imuvvpq9Zx2796NJ598EsOHD1cHLovFYug2kRWUH3nkEfTv31+dLEWwPisScIXj8aikNhE33XQTmjVrpi5cpJ7m8ccfV4HjTz/9ZNg22bhxowokpJ5C6iimTJmCjh07Yt26dRH9HvGnah9YGJ2cDHRSdCSBhhwIvv/++7A+4VNo/eUvf3F/LVdY8t5p1aqVymIMGjQIRibFdxJ4L168ONS7EvZtcs899xR7n0gBtLw/JBiV94sRyUWaBBGSwZk8eTJuvfVWLFiwINS7ZSjVvitEUnhyBeZduSvfp6SkwGgkmm7bti127dqlnp+k1U6fPl3qc5fbktpG/11Z95Gq6XAPXvTnUNbrL7fHjh0r9nup4pZREf5op+rwPpNuNPmsyPvGyG3y4IMPYtq0aZg3bx6aNGni/nmwPivheDwqrU1KIhcuwvN9YrQ2kayEjNTo1auXGjnTrVs3vPXWWxH9HvG3ah9YyJtE3iBz5swplvaT7yXdZTQyHFCuJuTKQp631Wot9twljSk1GPpzl1tJ/XmeRGbPnq3e5JL+0+/j+Rj6fapD+0mqXj6MnvsvKUepE/BsAzlYSL+mbu7cuep9oh9I5T4yhFP6WD3bQK5uJOVf3dvp4MGDqsZC3jdGbBOpYZUTqKS15Xl4d+EE67MSTsej8tqkJHIlLzzfJ0Zqk5LIvhQUFETkeyRgNAOQoTsyCmDChAmq2v2ee+5RQ3c8K3erq7///e/a/Pnztb1796qhfTLMSYY3SYW3PjxKhpDNnTtXDY/q27ev2ryHRw0dOlQNOZMhT/Xq1StxeNRjjz2mqqDfe++9sBpueubMGTW0SzZ5y77++uvq6/3797uHm8rr/fPPP2sbNmxQoyFKGm7ao0cPbcWKFdrixYu1Nm3aFBtaKRXhMrTy5ptvVkPP5D0lbeI9tDIqKkp77bXXVDvJiJ1QDTctq03kd//4xz9UJbu8b37//XetZ8+e6jnn5+cbsk3uv/9+NeRYPiueQydzc3Pd9wnWZyVcjkfltcmuXbu05557TrWFvE/k89OyZUttwIABhm2TJ554Qo2Kkecrxwr5XkZCzZo1KyLfI4FiiMBCyFhheUPI2GAZyiNj841Ahik1bNhQPa/GjRur7+WAoJOT5wMPPKCGTMmb+aqrrlIHD0/79u3Thg8fruYgkKBEghWbzVbsPvPmzdO6d++u/o8cXGT8e7iQfZOTp/cmQyr1IadPP/20OgnKh3XQoEFqjLqnEydOqJNmjRo11NCw22+/XZ2APckcGBdeeKF6DGlrCVi8ff/991rbtm1VO8mQMhkTH25tIicOOfDJAU9O8s2aNVPj5L0PWkZqk5LaQjbP93EwPyvhcDwqr03S0tJUEFGnTh31+so8JnIy9JzHwmhtcscdd6jPg+yDfD7kWKEHFZH4HgkULptOREREflPtayyIiIgofDCwICIiIr9hYEFERER+w8CCiIiI/IaBBREREfkNAwsiIiLyGwYWRERE5DcMLIiIiMhvGFgQERGR3zCwIKJKue222zBy5MhQ7wYRhSkGFkREROQ3DCyIqESTJ09Gly5dEBcXh+TkZAwePBiPPfYYvvjiC/z8888wmUxqmz9/vrr/gQMHcP3116NWrVqoU6cOrrzySuzbt88n0zF+/HjUq1dPLTV93333obCwMITPkoj8Lcrvj0hE1V56ejpuvPFGvPrqq7jqqqtw5swZLFq0CLfccgvS0tKQlZWFzz//XN1XggibzYZLL70Uffv2VfeLiorCCy+8gGHDhmHDhg2Ijo5W950zZw5iY2NVMCJBx+23366ClhdffDHEz5iI/IWBBRGVGFgUFRXh6quvRrNmzdTPJHshJINRUFCAlJQU9/2//vprOBwOfPLJJyqLISTwkOyFBBFDhw5VP5MA47PPPkN8fDw6deqE5557TmVBnn/+eZjNTKASGQE/yUTko1u3bhg0aJAKJq677jp8/PHHOHXqVKn3X79+PXbt2oXExETUqFFDbZLJyM/Px+7du4s9rgQVOslwZGdnq24UIjIGZiyIyIfFYsHs2bOxdOlSzJo1C++88w6eeuoprFixosT7S3DQq1cvfPPNNz6/k3oKIoocDCyIqETSpdG/f3+1PfPMM6pLZMqUKao7w263F7tvz5498d1336F+/fqqKLOszEZeXp7qThHLly9X2Y3U1NSAPx8iCg52hRCRD8lMvPTSS1i9erUq1vzpp59w/PhxdOjQAc2bN1cFmdu3b0dGRoYq3Bw1ahTq1q2rRoJI8ebevXtVbcVDDz2EgwcPuh9XRoDceeed2LJlC2bMmIFnn30WDz74IOsriAyEGQsi8iFZh4ULF+LNN99UI0AkW/Gf//wHw4cPR+/evVXQILfSBTJv3jwMHDhQ3f/xxx9XBZ8yiqRx48aqTsMzgyHft2nTBgMGDFAFoDLyZNy4cSF9rkTkXyZN0zQ/PyYRkQ+Zx+L06dOYOnVqqHeFiAKI+UciIiLyGwYWRERE5DfsCiEiIiK/YcaCiIiI/IaBBREREfkNAwsiIiLyGwYWRERE5DcMLIiIiMhvGFgQERGR3zCwICIiIr9hYEFERETwl/8HV0LM+wMYQOcAAAAASUVORK5CYII="
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 17
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 测试集"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T15:53:09.826607Z",
     "start_time": "2025-02-25T15:53:09.737664Z"
    }
   },
   "source": [
    "model.eval()\n",
    "loss = evaluating(model, val_loader, loss_fct)\n",
    "print(f\"loss:     {loss:.4f}\")"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss:     0.3414\n"
     ]
    }
   ],
   "execution_count": 18
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "pytorch",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.8"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
